1、准备工作
(1) 创建地面:3D Object-Plane,命名为Ground
(2) 创建小球:3D Object-sphere,命名为Player,PositionY= 0.5。添加Rigidbody组件
(3) 创建文件夹:Create-Foder,分别命名为Materials、Scripts、Audio
2、颜色设置
(1) 在Materials文件夹,Create-Material。命名为GroundMaterial,更改颜色(128,181,128)
颜色:透明度A(0~255) 红R(0~255) 绿G(0~255) 蓝B(0~255)


(2) 地面颜色:拖拽GroundMaterial 到Ground
(3) 小球颜色:同样的方法设置
2、使小球运动
(1) 原理:施加一个力(大小、方向、作用点)通过Input.GetAxes() 方法获取Axes中的名称
Edit-Project Setting

Input.GetAxis("Horizontal"):
获取水平轴的输入值。水平轴通常表示左右移动的输入。该函数会返回一个介于-1到1之间的值
即:玩家按下Negative Button,Horizontal 的取值向-1偏移(一般表示向左移)
玩家持续按住不放,Horizontal 持续为 -1。(方向持续向左)
当玩家没有输入或处于中立位置时,这个值通常接近 0
(2) 添加 PlayerCtrller.cs 组件
    public float speed = 10f;
    private Rigidbody rb;//声明刚体
    void Start()
    {
        rb =this.GetComponent<Rigidbody>();//获取挂载此脚本物体(小球)的Rigidbody组件,并将之赋值给rb;方便后续设置小球运动
    }
    void Update()
    {
        float moveH = Input.GetAxis("Horizontal");//获取水平轴的输入值,并赋值给moveH
        float moveV = Input.GetAxis("Vertical");//垂直方向
        //力的方向
        Vector3 movement = new Vector3(moveH, 0,moveV);
        //movement * speed:  力的方向和大小
        //将力施加到刚体上,使刚体(小球)根据物理规则移动。
        rb.AddForce(movement*speed);
    } 
3、创建环境
(1) 3D Object-Cube。命名为Wall。设置颜色、大小、位置
(2) 用同样的方法制作另外三面墙
4、创建旋转的金币
(1) 3D Object-Cube。设置颜色、大小、位置
(2) 旋转的原理
旋转角度的表示方式之一:欧拉角
旋转的顺序是:Z轴—X轴—Y轴
(3) CoinCtrller.cs 组件
    public float speed = 5f;
    void Update()
    {
        this.transform.Rotate(new Vector3(30,45,90)*speed*Time.deltaTime);
    } 
(4) 将金币制成预制件
5、接触事件——金币消失
(1) 打开PlayerCtrller.cs
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("coin"))
        {
            other.gameObject.SetActive(false);
        }
    } 
(2) 不必要缓存处理:
方法一:给金币添加Rigidbody组件(从静态Collider变为动态Collider)后勾选Is Kinematic或取消勾选Use Gravity

方法二:
        if (other.gameObject.CompareTag("coin"))
        {
            //Destroy(other.gameObject);
        }
 
6、镜头跟随
(1) 原理:使球与摄像机保持固定的角度和距离
(2) 给Main Camera添加CamraCtrller.cs组件
    public Transform Player;//小球的Transform
    private Vector3 offset;//小球与摄像机位置的偏移(在三轴上的距离)
    void Start()
    {
        offset = Player.position - this.transform.position;
    }
    void LateUpdate()
    {
        this.transform.position = Player.position-offset;
    } 
(3) 回到Unity赋值
7、PlayerCtrller.cs调整:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCtrler : MonoBehaviour
{
    public float speed = 10f;
    private float moveH = 0;
    private float moveV = 0;
    private Rigidbody rb;//声明刚体
    // Start is called before the first frame update
    void Start()
    {
        rb =this.GetComponent<Rigidbody>();//获取挂载此脚本物体(小球)的Rigidbody组件,并将之赋值给rb;方便后续设置小球运动
    }
    // Update is called once per frame
    void Update()
    {
        moveH = Input.GetAxis("Horizontal");//获取水平轴的输入值,并赋值给moveH
        moveV = Input.GetAxis("Vertical");//垂直方向
    }
    private void FixedUpdate()
    {
        //力的方向
        Vector3 movement = new Vector3(moveH, 0, moveV);
        //movement * speed:  力的方向和大小
        //将力施加到刚体上,使刚体(小球)根据物理规则移动。
        rb.AddForce(movement * speed);
    }
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("coin"))
        {
            other.gameObject.SetActive(false);//或者将other物体添加Rigidbody组件以清除缓存
            //Destroy(other.gameObject);
        }
    }
} 
注意:
若在Update中使用movement,需乘以Time.deltaTime以确保相同的速度在不同帧率下保持一致。而在FixedUpdate中使用movement时,不需要
8、UI交互——Score
(1) UI-Text,命名ScoreText。宽高:240*64;Alt+左上角锚点。文本改为Score,改变字号、颜色
(2) 打开PlayerCtrller.cs
using UnityEngine.UI;
    
private int score = 0;
public Text scoreText;
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("coin"))
        {
            //……
            score++;
            scoreText.text ="Score:" + score.ToString();
        }
    } 
(3) 赋值
9、UI交互——Win
(1) UI-Text,命名WinText。Reset。宽高:240*128;。文本改为Win,改变字号、颜色,居中
(2) 打开PlayerCtrller.cs
    public Text winText;
    void Start()
    {
        ……
        winText.gameObject.SetActive(false);
    }
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("coin"))
        {
            ……
            if (score == 4)
            {
                winText.gameObject.SetActive(true);//显示文本物体
            }
        }
    }
 
10、UI交互——按钮_01(出现和隐藏)
(1) UI-Button (Legacy),命名为RestartBtn。调整位置(-200,-100)和文本内容Restart
(2) UI-Button (Legacy),命名为QuitBtn。调整位置(200,-100)和文本内容Quit
(3) 打开PlayerCtrller.cs
    public Button restartBtn;
    public Button QuitBtn;
    void Start()
    {
        ……
        restartBtn.gameObject.SetActive(false);//隐藏按钮物体
        QuitBtn.gameObject.SetActive(false);//隐藏按钮物体
    }
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("coin"))
        {
            ……
            if (score == 4)
            {
                ……
                restartBtn.gameObject.SetActive(true);
                QuitBtn.gameObject.SetActive(true) ;
            }
        }
    }
 
(4) 赋值
10、UI交互——按钮_02(按钮事件)
(1) 在Canvas下,Create Empty。命名为BtnCtrller
(2) 给空物体BtnCtrller添加BtnCtrller.cs
using UnityEngine.SceneManagement;
public class BtnCtrller : MonoBehaviour
{
    public void OnRestart()
    {
        SceneManager.LoadScene("SampleScene");
    }
    public void OnQuit()
    {
        Application.Quit();//退出
    }
}
 
(2) 设置按钮的On Click
11、添加音效
(1) 将背景音乐 bgAudio 拖放到Hierarchy面板
(2) 选中 bgAudio,勾选开始运行就播放、循环播放。调节音量(volume)
![]()
(3) 将吃金币音效拖放到Hierarchy面板的Player上
(4) 选中 Player,取消勾选开始运行就播放、循环播放。调节音量(volume)
(5) 打开PlayerCtrller.cs
    public AudioSource triggerAudio;
        if (other.gameObject.CompareTag("coin"))
        {
            ……
            triggerAudio.Play();
            score++;
            ……
            }
 
(6) 赋值
(7) 同样的方法添加Win音乐
(8) 游戏结束,音乐停止
    public AudioSource bgAudio;
            if (score == 4)
            {
                ……
                bgAudio.Stop();
            }
                
12、安卓版打包——添加手柄
(1) 下载并导入 资源包
(2) 打开Prefabs 文件夹,将 Fixed Joystick 拖放到Hierarchy面板上,调整大小和位置
(3) 打开PlayerCtrller.cs,调整脚本
    public FixedJoystick fixedJoystick;
    void Start()
    {
        ……
        fixedJoystick = GameObject.FindObjectOfType<FixedJoystick>();
    }
    private void FixedUpdate()
    {   
        ……
        //力的方向
        //Vector3 movement = new Vector3(moveH, 0, moveV);
        Vector3 movement = Vector3.forward* fixedJoystick.Vertical + Vector3.right * fixedJoystick.Horizontal;
        ……
    }
 
 
 
 
 
                


















