欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

实战演练 飞盘射击 要点汇总

程序员文章站 2022-07-11 11:40:21
...

Model的mesh filter 和mesh collider

将model移入scene中时,应拖拽到左边名称栏而非*视图区。
mesh filter是 网格过滤器,用于剪裁mesh,形成物体几何形状,再交给mesh renderer网格渲染器渲染。
mesh collider是 碰撞器的一种,用于碰撞。
这两者都可以选择mesh, filter应该选择高模, collider应选择低模,
实战演练 飞盘射击 要点汇总

射击手臂随鼠标移动而转动

首先得先创一个空物体将其调整位置到大臂末端(转动中心)后再把它作为手臂的父物体(先后不能反)。
创空物体的技巧:在手臂上右键创建空物体,会创建到相同位置。
方法1:
主摄像机发射射线到鼠标位置,用变量接受这根射线,用Physics.Raycast(ray, out hit)的方法把射出射线去碰撞,获得hit碰撞点信息,再利用Transform的LookAt来指向这个碰撞点hit.point。
缺点:需要碰撞,若无碰撞,手臂不转动。

//初始化的已省略
        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit))//需要给背景装上mesh  collider
        {
            m_Transform.LookAt(hit.point);
        }
        else
        {
            Debug.Log("no collider");
        }

Input.mousePosition介绍:
Input.mousePosition返回当前鼠标的位置,这里指的是距离原点的像素位置,说明一下,Unity中的原点(0,0)位置为左下角,上位y轴正方向,右为x轴正方向。返回值类型为Vector3,默认z为0。
实战演练 飞盘射击 要点汇总

public class mono2 : MonoBehaviour {
     void OnGUI(){
               GUI.Label(new Rect(100,100,400,100),"x="+Input.mousePosition.x+"  y="+Input.mousePosition.y+"  z="+Input.mousePosition.z);         
     }//放在类里,update()外
}

因此 将方法1改成 直接 m_Transform.LookAt(Input.mousePosition); 会导致,鼠标放到左下角,(0,0,0)左右的时候,手臂指向正前方,也因为主摄像机在(0,0,-4)的地方,所以lookat的时候就指向了正前方。

枪口发射激光

先建立一个位于枪口的空物体,成为手臂子物体(为了保证同步运动),再给枪口或者手臂添加LineRenderer组件,此组件parameter中可以修改颜色,宽度。
LineRenderer.SetPosition(int index, Vector3 position) 用于设置第index个节点的位置
其中需要枪口位置,碰撞点位置。碰撞点位置可以用hit.point
枪口位置可以用Transform.postion 但需要从父物体的Transform中.FindChild(“Point”)来查找枪口的Transform组件。

延时功能

可以用协程,用法:

void crashdown(float time)//time是延迟时间
{
   StartCoroutine(crash_down(time));
}

IEnumerator crash_down(float time)//IEnumerator是返回值类型!
{
    yield return new WaitForSeconds(time); //要new! 
    //gameobject与Transform都有.GetComponentsInChildren<>()!!
    Transform[] children_Transform = gameObject.GetComponentsInChildren<Transform>();
    for (int i = 0; i < children_Transform.Length; i++)
    {
        children_Transform[i].gameObject.AddComponent<Rigidbody>();
    }
}

也可以在sendmessage的cs文件里写StartCoroutine, 将sendmessage写在里面。

StartCoroutine(crashdown(time, hit.transform.parent));
...
IEnumerator crashdown(float time, Transform m_Transform)
{
    yield return new WaitForSeconds(time);
    m_Transform.SendMessage("crash_down"); //Transform组件也可以SendMessage
}

另外! GameObject.Destroy(gameobject, 8.0f) 删除物体自带延迟!
同样Invoke(“”, 5.0f) 也可以延迟调用函数
InvokeRepeating( “”, 5.0f, 3.0f) 5秒后开始每3秒调用一次函数

hit碰撞点信息的使用

hit.point 是碰撞点位置
hit.transform 是碰撞的物体的Transform组件
hit.collider 是碰撞的物体的Collider组件
要找碰撞的tag,可以用 hit.transform.gameObject.tag也可以直接hit.transform.tag 也可以hit.collider.tag

射中飞盘效果

可以直接消失,用GameObject.Destroy(hit.transform.parent, 0.5f) 0.5秒后将父物体销毁
也可以破碎,给所有子物体加rigidbody组件,
Transform[] pieces = hit.transform.parent.GetComponentsInChiledren< Transform >()
for循环 ..每一个都 addComponent< rigidbody>
再GameObject.Destroy(hit.transform.parent, 1.5f) 过一会销毁