实战演练 飞盘射击 要点汇总
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) 过一会销毁
推荐阅读