Unity运动轨迹_跟踪导弹

前言

        这个一个2d游戏的跟踪导弹游戏,这个轨迹有两个要点:1.实现跟踪、2.轨迹成弧线。

效果 

逻辑

        1.实现跟踪:子弹一直朝着目标移动。

               求得目标的方向:   

                        dir = target - self.position;

                利用unity 中的正切函数取得该方向在世界左边下的角度:

                       angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;

                得到角度旋转子弹方向:

                      self.rotation = Quaternion.AngleAxis(angle, Vector3.forward);

        2.实现轨迹弧线:在朝向目标后在加一个旋转,随着靠近目标这个旋转逐渐减小。

      代码

        

using System;
using System.Timers;
using Unity.Mathematics;
using UnityEngine;
using Random = UnityEngine.Random;

/// <summary>
/// 追踪弹
/// </summary>
public class Track : MonoBehaviour
{
    // 子弹
    private Rocket _self;
    [Header("移动速度")]
    public float moveSpeed= 5;                //移动速度
    [Header("随机扭曲弹道")]
    public float RandomRotateMin = -50;    //随机旋转角度
    public float RandomRatateMax = +50;
    
    private float RandomRotate;
    private Transform target;               //跟踪目标

    // 距离敌人距离
    private float _targetDis;
    
    private void Start()
    {
        // 初始化
        _self = GetComponent<Rocket>();
        target = _self.Target;
        
        // 随机角度值
        RandomRotate = Random.Range(RandomRotateMin, RandomRatateMax);
        // 距离敌人距离
        _targetDis = Vector3.Distance(transform.position, target.position);
    }

    private void Update()
    {
        TrackUnit();
    }
    
    private void TrackUnit()
    {
        if (target != null)    //判断当前是否有跟踪目标 如果有的话 执行 以下跟踪逻辑
        {
            // 追踪
            TrackUnit(transform,target.position);
            // 扭曲
            var rotateValue = RandomRotate;
            
            // 距离比例
            var disRatio = Vector3.Distance(transform.position, target.position) / _targetDis;
            // 根据距离控制扭曲角度
            if (disRatio > 1)
                rotateValue = 0;
            else if(disRatio < 1)
                rotateValue = RandomRotate * disRatio;
            
            // 限制扭曲角度范围
            rotateValue = Mathf.Clamp(rotateValue, RandomRotateMin, RandomRatateMax);
            // 扭曲弹道
            transform.rotation *= Quaternion.Euler(new Vector3(0,0,rotateValue));
        }
        //向前移动
        transform.position += transform.up * (moveSpeed * Time.deltaTime);     
    }
    
    /// <summary>
    /// 用某个轴去朝向物体 (这也是看向目标的方法可用于3d跟踪导弹)
    /// </summary>
    /// <param name="tr_self">朝向的本体</param>
    /// <param name="lookPos">朝向的目标</param>
    /// <param name="directionAxis">方向轴,取决于你用那个方向去朝向</param>
    void AxisLookAt(Transform tr_self, Vector3 lookPos, Vector3 directionAxis)
    {
        var rotation = tr_self.rotation;
        var targetDir = lookPos - tr_self.position;
        
        //指定哪根轴朝向目标,自行修改Vector3的方向
        var fromDir = tr_self.rotation * directionAxis;
        
        //计算垂直于当前方向和目标方向的轴
        var axis = Vector3.Cross(fromDir, targetDir).normalized;
        
        //计算当前方向和目标方向的夹角
        var angle = Vector3.Angle(fromDir, targetDir);
        
        //将当前朝向向目标方向旋转一定角度,这个角度值可以做插值
        tr_self.rotation = Quaternion.AngleAxis(angle, axis) * rotation;
    }
    
    // 扭转
    void TrackUnit(Transform self,Vector3 target)
    {
        var dir = target - self.position;
        // 世界坐标系下的角度
        var angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
        // 旋转z轴 这里 -90 是为了让 Y轴对齐目标
        self.rotation = Quaternion.AngleAxis(angle - 90f, Vector3.forward);
    }
}

                

  • 12
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值