您的位置:首页 > 移动开发 > Unity3D

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

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

    为了这个功能,花费了不少时间



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

注意

             发射角度(这里是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;       //累计消耗时间
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  unity 函数 c# 脚本 class