Unity制作Roll-a-Ball游戏

来源:互联网 发布:mysql 触发器原理 编辑:程序博客网 时间:2024/06/05 02:22

,DirectionalLight的效果由Rotation决定而不是Position。

创建了新的object一定要先reset。

FrameSelected用于将摄像机对准某个object。

想要object有力的效果或是匀速移动,或识别撞击(Collider/Trigger),需对其添加rigidbody组件,同时编写的相关程序脚本也在相应object中添加。

左右运动在X轴,前后运动在Z轴。

使小球运动的代码:

public class playercontroller : MonoBehaviour {public float speed;/**这个选项可以在player的Inspector中输入*/void FixedUpdate()/**与物理相关的代码卸载这个方法里*/{    float moveHorizontal = Input.GetAxis ("Horizontal");/**水平方向的移动输入,左右*/    float moveVertical = Input.GetAxis ("Vertical");/**垂直方向上的移动输入,前后*/Vector3 movement = new Vector3 (moveHorizontal, 0.0f,moveVertical);/**movement中存放了各方向上移动的数据*/    GetComponent<Rigidbody>().AddForce(movement*speed*Time.deltaTime);/*通过movement做参数,决定了施加力的方向和大小*/}}

建立摄像机与小球间联系的代码:

public class CameraContrlloer : MonoBehaviour {public GameObject player;private Vector3 offset;/**定义摄像机与小球间的距离*/// Use this for initializationvoid Start () {    offset = transform.position;/**将距离初始化为摄像机的位置,非常巧妙的技巧,因为我们一般将要跟随的对象位置初始化为原点,只需要在一开始调整好摄像机的位置,之后就会保留下去*/}void LateUpdate () {    transform.position = player.transform.position + offset;}}

注意:要把player拖入到camera Inspector的脚本选项里。

拾取物体的旋转代码:

public class rotation : MonoBehaviour {// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {    transform.Rotate(new Vector3(15,30,45)*Time.deltaTime);}}

在移动物体时Local模式是绕着自己的轴移动(空间中移动),Global模式是在平面上移动。注意:切换为Global模式后直接用鼠标左右画圈拖拽,不要直接上下拖拽,否则object还是在空间中而非平面上运动。

Prefab文件夹保存各种可以在任何项目中调用的素材。

OnTriggerEnter(Collider other)这个函数在球第一次碰到TriggerCollider时调用,再将碰到的Collider暂存在other中。

拾取物体的代码:

void OnTriggerEnter(Collider other){    if(other.gameObject.tag == "PickUp")/**tag就是object的标签,需要在inspector中设定,常用来做判断*/    {        other.gameObject.SetActive(false);/**禁用碰撞到的object*/    }}

在计算碰撞时,静态物体不会被影响,而动态物体会被影响(比如:小球撞到cube会弹开一下,而cube什么事都没有)

除了设置tag值外,我们还需要将Collider设置为TriggerCollider(即在被拾取的各cube中的将IsTrigger打钩),因为拾取过程说白了是一个“触发”。

关于此过程的优化:

有rigidbody的为动态物体,没有的为静态物体。对于静态物体而言,发生移动,旋转,拉伸时unity引擎会计算静态碰撞器的体积并实时上传到Cash,为了节省这部分资源,我们将所有cube添加Rigidbody,将其变为动态物体。(可以用cltr快捷键完成对多个Object的操作)这时发现它们全都穿过Ground掉下去了,这是因为作为刚体考虑力的影响,而Istrigger(触发器)不会与Ground发生碰撞,由于重力便掉下去了,所以我们要设置为忽视重力。

关于Rigidbody:

刚体使物体能在物理控制下运动。刚体可通过接受力与扭矩,使物体像现实方式一样运动。任何物体想要受重力影响,受脚本施加的力的作用,或通过NVIDIA PhysX物理引擎来与其他物体交互,都必须包含一个刚体组件。

Is Kinematic 是否是运动学If enabled, the object will not be driven by the physics engine, and can only be manipulated by its Transform. This is useful for moving platforms or if you want to animate a Rigidbody that has a HingeJoint attached.若激活,该物体不再受物理引擎驱动,而只能通过变换来操作。适用于模拟运动的平台或者模拟受铰链关节连接的刚体。 

勾选各cube的Is Kinematic选项,相当于把他们变成不受力影响的动态物体。
利用脚本控制UIText的显示内容并在win后等待两秒退出游戏(player的最终脚本):

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;public class playercontroller : MonoBehaviour{public float speed;private int count;public Text CountText;private void Start(){    count = 0;    CountText.text = "Count:" + count;}void FixedUpdate(){    float moveHorizontal = Input.GetAxis("Horizontal");    float moveVertical = Input.GetAxis("Vertical");    Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);    GetComponent<Rigidbody>().AddForce(movement * speed * Time.deltaTime);}IEnumerator MyMethod()/**要想实现停留若干秒,必须写这样一个方法,再通过协程调用这个方法完成停留若干秒后执行某操作*/{    Debug.Log("Before Waiting 2 seconds");    CountText.text = "you win!";/**在停留2s前执行的操作*/    yield return new WaitForSeconds(2);    Debug.Log("After Waiting 2 Seconds");    Apllication.Quit();/**在停留2s后执行的操作*/}void OnTriggerEnter(Collider other){    if (other.gameObject.tag == "PickUp")    {        other.gameObject.SetActive(false);        count = count + 1;        if (count == 8)        {            StartCoroutine(MyMethod());/**注意这里不是普通的调用而是采用协程调用*/        }        else        {            CountText.text = "Count:" + count;        }    }}}
原创粉丝点击