[Unity实战]屏幕追踪显示目标
2016-02-29 20:24
696 查看
参考链接:http://www.manew.com/thread-48125-1-1.html?_dsign=4edc9052
效果图:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public enum BeaconMoveType
{
Rect, //矩形
Rllipse, //椭圆
}
public class Beacon : MonoBehaviour {
private Transform player;
private Transform target;
private List<GameObject> targetList = new List<GameObject>();
private float width;
private float height;
public float range = 5f;//在范围内就不显示,否则显示
public BeaconMoveType beaconMoveType;
public void SetTarget(Transform target)
{
this.target = target;
}
public void SetTarget()
{
if (targetList.Count > 0)
{
targetList.Sort((a, b) =>
{
float disA = MathTool.GetDistance(a.transform, player);
float disB = MathTool.GetDistance(b.transform, player);
return disA.CompareTo(disB);
});
float dis = MathTool.GetDistance(targetList[0].transform, player);
if (dis > range) target = targetList[0].transform;
else target = null;
}
}
void Start ()
{
player = CharacterManager.Instance.player.transform;
targetList = CharacterManager.Instance.enemyCampGo;
//因为描点默认为中心,所以UI的移动范围为:
//x:-Screen.width / 2 - Screen.width / 2
//y:-Screen.height / 2 - Screen.height / 2
//50是偏移量
width = Screen.width / 2 - 50;
height = Screen.height / 2 - 50;
}
void Update ()
{
SetTarget();
if ((player == null) || (target == null))
{
transform.localScale = Vector3.zero;//隐藏
return;
}
else
{
transform.localScale = Vector3.one;//显示
}
Vector3 dir = (target.position - player.position).normalized;
dir.y = 0;
float dot = Vector3.Dot(dir, Vector3.forward);//以Vector3.forward为基准
float angle = Mathf.Acos(dot) * Mathf.Rad2Deg;
Vector3 cross = Vector3.Cross(dir, Vector3.forward);//判断左右
//Debug.Log("角度:" + angle + "---" + (cross.y > 0?"左边":"右边"));
transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle * (cross.y > 0 ? 1 : -1)));
Vector3 pos = Vector3.zero;
if (angle == 0) pos = new Vector3(0, height, 0);
else if (angle == 180) pos = new Vector3(0, -height, 0);
else
{
//1.椭圆方程
//焦点在x轴:x²/a²+ y²/b²=1 (a>b>0)
//焦点在y轴:y²/a²+ x²/b²=1 (a>b>0)
//2.k = x / y
//k在0-90度时大于0,90-180度时小于0
float k = Mathf.Tan(angle * Mathf.Deg2Rad);
k = Mathf.Abs(k);//排除符号的影响
switch (beaconMoveType)
{
case BeaconMoveType.Rllipse:
pos.y = width * height * Mathf.Sqrt((1f / (width * width + height * height * k * k)));
pos.x = pos.y * k;
if (angle > 90f) pos.y = -pos.y;//目标在背后
if (cross.y > 0f) pos.x = -pos.x;//目标在左边
break;
case BeaconMoveType.Rect:
pos.x = height * k;
if ((pos.x > -width) && (pos.x < width))//在矩形区域的上边或者下边
{
pos.y = height;
}
else//在矩形区域的左边或者右边
{
pos.x = width;
if(k != 0f) pos.y = pos.x / k;
}
if (angle > 90f) pos.y = -pos.y;//目标在背后
if (cross.y > 0f) pos.x = -pos.x;//目标在左边
break;
default:
break;
}
}
transform.localPosition = pos;
}
}
效果图:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public enum BeaconMoveType
{
Rect, //矩形
Rllipse, //椭圆
}
public class Beacon : MonoBehaviour {
private Transform player;
private Transform target;
private List<GameObject> targetList = new List<GameObject>();
private float width;
private float height;
public float range = 5f;//在范围内就不显示,否则显示
public BeaconMoveType beaconMoveType;
public void SetTarget(Transform target)
{
this.target = target;
}
public void SetTarget()
{
if (targetList.Count > 0)
{
targetList.Sort((a, b) =>
{
float disA = MathTool.GetDistance(a.transform, player);
float disB = MathTool.GetDistance(b.transform, player);
return disA.CompareTo(disB);
});
float dis = MathTool.GetDistance(targetList[0].transform, player);
if (dis > range) target = targetList[0].transform;
else target = null;
}
}
void Start ()
{
player = CharacterManager.Instance.player.transform;
targetList = CharacterManager.Instance.enemyCampGo;
//因为描点默认为中心,所以UI的移动范围为:
//x:-Screen.width / 2 - Screen.width / 2
//y:-Screen.height / 2 - Screen.height / 2
//50是偏移量
width = Screen.width / 2 - 50;
height = Screen.height / 2 - 50;
}
void Update ()
{
SetTarget();
if ((player == null) || (target == null))
{
transform.localScale = Vector3.zero;//隐藏
return;
}
else
{
transform.localScale = Vector3.one;//显示
}
Vector3 dir = (target.position - player.position).normalized;
dir.y = 0;
float dot = Vector3.Dot(dir, Vector3.forward);//以Vector3.forward为基准
float angle = Mathf.Acos(dot) * Mathf.Rad2Deg;
Vector3 cross = Vector3.Cross(dir, Vector3.forward);//判断左右
//Debug.Log("角度:" + angle + "---" + (cross.y > 0?"左边":"右边"));
transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle * (cross.y > 0 ? 1 : -1)));
Vector3 pos = Vector3.zero;
if (angle == 0) pos = new Vector3(0, height, 0);
else if (angle == 180) pos = new Vector3(0, -height, 0);
else
{
//1.椭圆方程
//焦点在x轴:x²/a²+ y²/b²=1 (a>b>0)
//焦点在y轴:y²/a²+ x²/b²=1 (a>b>0)
//2.k = x / y
//k在0-90度时大于0,90-180度时小于0
float k = Mathf.Tan(angle * Mathf.Deg2Rad);
k = Mathf.Abs(k);//排除符号的影响
switch (beaconMoveType)
{
case BeaconMoveType.Rllipse:
pos.y = width * height * Mathf.Sqrt((1f / (width * width + height * height * k * k)));
pos.x = pos.y * k;
if (angle > 90f) pos.y = -pos.y;//目标在背后
if (cross.y > 0f) pos.x = -pos.x;//目标在左边
break;
case BeaconMoveType.Rect:
pos.x = height * k;
if ((pos.x > -width) && (pos.x < width))//在矩形区域的上边或者下边
{
pos.y = height;
}
else//在矩形区域的左边或者右边
{
pos.x = width;
if(k != 0f) pos.y = pos.x / k;
}
if (angle > 90f) pos.y = -pos.y;//目标在背后
if (cross.y > 0f) pos.x = -pos.x;//目标在左边
break;
default:
break;
}
}
transform.localPosition = pos;
}
}
相关文章推荐
- 关于AlphaTest
- Unity3D学习笔记(1)
- Unity2D多分辨率屏幕适配方案
- Unity3D导入图片大小被改变
- Unity简易数据库之Sqlite
- Unity NGUI实现 点击弹窗跟随鼠标点击位置
- 利用Unity播放视频剪影!BadApple
- Unity调用Android
- Unity NGUI panel 实现层级管理 即点谁谁置顶
- unity3d限定一个数的取值范围
- Unity3D DLL加密
- Unity Tween tool
- 分享2D Unity游戏的动画制作经验
- Unity3D发布Android应用使用友盟统计代码
- unity 背景动态模糊(blur)和截屏方法
- 在Unity3D中基于订阅者模式实现事件机制
- 扩展Unity3D编辑器的脚本模板
- unity3d,异步加载场景
- Unity3D-Invoke()
- Unity3D-Input类Axes自定义