unity。。可指定目标点的类弓箭斜抛运动控制C#脚本(不采用物理引擎)。。纯位移旋转控制

    xiaoxiao2021-03-25  71

        这是一个完整的脚本,箭在对象手里(子级)。。还有射击精度控制。。。你可以只看你需要的功能即可。。。

        为了这个功能,花费了不少时间。。还意外发现,游戏中的模型的大小比例会影响物理效果,得到的结果和用笔实际计算的不一样!!(不知道对不对,还请知道的大神麻烦留言解释下,谢谢了)。。。。所以:

    注意:

                 发射角度(这里是45),如果你达不到效果(射中目标),请自己更改。还有标注为*****那行的*2。。。是

    一个特殊值(我也没弄明白,还请大神赐教)。。。也请自己更改。。。。。

    /华丽的分割线

    using UnityEngine;

    using System.Collections; //斜抛运动轨迹控制脚本 public class ThrowMoveTrailControl : MonoBehaviour {     private Transform shoot_enemy=null;       //获取目标位置     private float R=0;          //射击精度控制,     private float distance_h=0;     private float real_distance_h = 0;     private Vector3 pos;     private Vector3 world_pos_self;     private Vector3 world_pos_enemy;     private Vector3 real_shoot_pos;     private float shoot_radian;     //射击弧度     private float shoot_speed;      //发射速度     private float delta_time=0;       //从开始发射到现在消耗的时间     private float cos_radian;     private float sin_radian;     private float angle_x;          //发射方向离世界x轴的夹角     private float angle_z;          //发射方向离世界z轴的夹角     private Vector3 start_world_pos;        //箭发射那一刻的世界坐标     ///抛物线坐标点在各个坐标轴的投影     private float move_x=0;     private float move_y=0;     private float move_z=0;

        const float G = 9.8f; //重力加速度

    //先初始化这个箭   

        // be call before function:start()     private void Awake()     {         KulouArcherActions k=null;         k=transform.GetComponentInParent<KulouArcherActions>();         if(k==null) Debug.Log("the arrow have not shoot enemy??????????");         shoot_enemy=k.close_enemy.transform;        //get the shoot position         pos = new Vector3();         real_shoot_pos = new Vector3();         transform.parent = null;            //把箭移出所有父级         shoot_radian = 45* Mathf.PI / 180;         cos_radian = Mathf.Cos(shoot_radian);         sin_radian = Mathf.Sin(shoot_radian);         ready();     }     void ready()     {         world_pos_self = transform.TransformPoint(Vector3.zero);         world_pos_enemy = shoot_enemy.TransformPoint(Vector3.zero);         pos.Set(world_pos_self.x, world_pos_enemy.y, world_pos_self.z);         distance_h = Vector3.Distance(pos, world_pos_enemy);       //世界坐标的水平距离         /计算在有射击精度误差的情况下         R = (distance_h - 1f) * 0f;        //1 as attack distance         real_shoot_pos.Set((world_pos_enemy.x + Random.Range(-R, R)), world_pos_self.y,             (world_pos_enemy.z + Random.Range(-R, R)));                 //以目标为中心,R为半径的一个圆作为误差范围         real_distance_h = Vector3.Distance(world_pos_self,real_shoot_pos);         shoot_speed = Mathf.Sqrt(real_distance_h * G /2*sin_radian*cos_radian) *2;          //*********************         angle_x = Vector3.Angle(real_shoot_pos - world_pos_self, Vector3.right);    //获取和世界x轴夹角         angle_z = Vector3.Angle(real_shoot_pos - world_pos_self, Vector3.forward);  //获取和世界z轴夹角         start_world_pos =world_pos_self;         

        }

    ///开始按帧移动

    // Update is called once per frame void Update ()     {         distance_h = shoot_speed * cos_radian*delta_time;           //由消耗时间计算总的水平移动距离         move_z = distance_h * Mathf.Cos(angle_z * Mathf.PI / 180);  //算出这个向着目标移动的水平距离投影到各个坐标的实际移动值         move_x = distance_h * Mathf.Cos(angle_x * Mathf.PI / 180);         move_y = (shoot_speed * delta_time * sin_radian - G * delta_time * delta_time * 0.5f);         pos.Set(start_world_pos.x + move_x, start_world_pos.y+move_y, start_world_pos.z +move_z);//由初始的坐标加上本帧需要移动的,由此来连续移动         transform.rotation = Quaternion.FromToRotation(Vector3.left, pos - transform.position);//旋转箭头,指向下一个移动的坐标点         transform.position=pos;         delta_time += Time.deltaTime;       //累计消耗时间 } }
    转载请注明原文地址: https://ju.6miu.com/read-36014.html

    最新回复(0)