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

Unity3d Note2

程序员文章站 2024-01-24 20:02:52
...

游戏对象运动的本质是什么?

游戏对象运动的本质就是transform属性坐标的连续改变
我们想让位置随时间连续变化,而update()函数是每帧被调用一次,而帧率在不断变化,Update()被调用的时间并不是线性的,所以需要乘以帧间时间,也就是Time.DeltaTime。

void Update () {
     this.transform.position += Vector3.left * Time.deltaTime;
}

用三种以上方法,实现物体的抛物线运动

使用transform.position方法

public float speed = 1.0f;
void Update () {
    speed += 0.1f;
    this.transform.position += speed * Vector3.up * Time.deltaTime;
    this.transform.position += Vector3.left * Time.deltaTime;
}

使用transform.translate()方法

public float speed = 1.0f;
void Update()
{
    speed += 0.05f;
    transform.Translate(speed * Vector3.up * Time.deltaTime);
    transform.Translate(Vector3.left * Time.deltaTime);
}

使用Vector3.MoveTowards()方法

float t = 0.0f;

void Start()
{
    transform.position = new Vector3(0.0f, 0.0f, 0.0f);
}

void FixedUpdate()
{
     t += Time.fixedDeltaTime;
     transform.position = Vector3.MoveTowards(transform.position, new Vector3(t, t * t, 0), Time.fixedDeltaTime);
}

通过添加刚体属性,并设置恒力和速度

public float speed = 1.0f;
public Rigidbody rb;

void FixedUpdate()
{
    rb.velocity = new Vector3(1f, 0, 0);
    rb.AddForce(0, speed, 0, ForceMode.Impulse);
}

写一个程序,实现一个完整的太阳系, 其他星球围绕太阳的转速必须不一样,且不在一个法平面上

transform.RotateAround()的第一个参数指定围绕旋转的坐标点,第二个参数表示围绕旋转的法向量,第三个参数表示旋转的速度。由于我们要围绕太阳旋转,所以第一个参数设为太阳的坐标,也就是原点,第二个参数和第三个都使用随机生成的数值。然后把这个脚本挂载到行星上,就可以旋转了。

public class NewBehaviourScript : MonoBehaviour {

    public float speed;
    float rz, rx, ry;
    // Use this for initialization  
    void Start()
    {
        speed = Random.Range(10, 40);
        rx = Random.Range(0, 20);
        ry = Random.Range(0, 20);
        rz = Random.Range(0, 20);
    }

    // Update is called once per frame  
    void Update()
    {
        Vector3 axis = new Vector3(0, ry, rz);
        this.transform.RotateAround(new Vector3(0, 0, 0), axis, speed * Time.deltaTime);
    }
}

将月球设为地球的子对象,然后讲上面的脚本的太阳坐标改为地球的,就可以使月球围绕地球旋转。

public class NewBehaviourScript1 : MonoBehaviour {
    public Transform origin;
    public float speed;
    float rz, rx, ry;
    // Use this for initialization  
    void Start()
    {
        speed = Random.Range(10, 40);
        rx = Random.Range(0, 20);
        ry = Random.Range(0, 20);
        rz = Random.Range(0, 20);
    }

    // Update is called once per frame  
    void Update()
    {
        Vector3 axis = new Vector3(0, ry, rz);
        this.transform.RotateAround(origin.position, axis, speed * Time.deltaTime);
    }
}

设置地球自转,将围绕旋转设为自己的坐标,并调整一下旋转法向量和速度即可。

public class NewBehaviourScript2 : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        this.transform.RotateAround(this.transform.position, Vector3.up, 2);
    }
}

效果图
Unity3d Note2

牧师与恶魔

效果图
Unity3d Note2

游戏中提及的事务
Unity3d Note2

玩家动作表

  • 点击牧师
  • 点击恶魔
  • 点击船只
  • 点击重新开始按钮

主要参考博客https://www.jianshu.com/p/07028b3da573实现
添加了一些拓展功能

  • 开始按钮Start
  • 计时功能Time Left
  • 游戏开始之前和失败以后不能再响应用户点击的事件,用户只能点击Start和Restart

修改代码,在UserAction接口中添加属性 bool IsStop 来判断是否响应用户事件
修改UserGUI

private float time = 0;
private bool isIni=false;

void Update()
{
    if (!action.IsStop)
        time += Time.deltaTime;
}
void OnGUI()
{
    if (isIni == false)
    {
        if (GUI.Button(new Rect(Screen.width / 2 - 70, Screen.height / 2, 140, 70), "Start", buttonStyle))
        {
            action.IsStop = false;
            isIni = true;
        }
    }
    GUI.Label(new Rect(Screen.width - 100, 0, 100, 50), "Time Left:" + Mathf.RoundToInt(60 - time));
    if (Mathf.RoundToInt(time) == 60)
    {
        action.IsStop = true;
        GUI.Label(new Rect(Screen.width / 2 - 50, Screen.height / 2 - 85, 100, 50), "Timeout!", style);
        if (GUI.Button(new Rect(Screen.width / 2 - 70, Screen.height / 2, 140, 70), "Restart", buttonStyle))
        {
            time = 0;
            action.IsStop = false;
            status = 0;
            action.restart();
        }
        return;
    }
    if (status == 1)
    {
        action.IsStop = true;
        GUI.Label(new Rect(Screen.width / 2 - 50, Screen.height / 2 - 85, 100, 50), "Gameover!", style);
        if (GUI.Button(new Rect(Screen.width / 2 - 70, Screen.height / 2, 140, 70), "Restart", buttonStyle))
        {
            status = 0;
            action.restart();
            time = 0;
        }
    }
    else if (status == 2)
    {
        action.IsStop = true;
        GUI.Label(new Rect(Screen.width / 2 - 50, Screen.height / 2 - 85, 100, 50), "You win!", style);
        if (GUI.Button(new Rect(Screen.width / 2 - 70, Screen.height / 2, 140, 70), "Restart", buttonStyle))
        {
            status = 0;
            action.restart();
            time = 0;
        }
    }
}
相关标签: Unity3d