【Unity知识树】基于Unity的C#游戏工程(拉方块小游戏)超详细代码注释

 

 

PlayerController.cs

//PlayerController.cs
using UnityEngine;
/// <summary>
/// 挂Player身上
/// </summary>
public class PlayerController : MonoBehaviour
{
    PlayerCharacter character; //声明角色功能脚本
    void Start()
    {
        character = GetComponent<PlayerCharacter>(); //获取
    }
    void Update()
    {
        //获取水平和垂直轴输入来进移动
        character.Move(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
        character.PosLimit(); //位置限制
        character.BodyCharacter(); //身体控制        
        //鼠标左键激活拉伸技能
        if (Input.GetMouseButtonDown(0))
            character.stretching = true;
        character.Pull(); //拉伸
        character.PickUp(); //拿起
        //鼠标右键放下箱子
        if (Input.GetMouseButtonDown(1))
            character.PutDown();
    }
}

PlayerCharacter.cs 

//PlayerCharacter.cs
using UnityEngine;
/// <summary>
/// 挂Player身上
/// </summary>
public class PlayerCharacter : MonoBehaviour
{
    Rigidbody rigid; //声明变量:刚体组件
    Transform body; //声明变量:身体
    Transform hand; //声明变量:手臂
    private void Start()
    {
        //获取刚体组件
        rigid = GetComponent<Rigidbody>();//给变量赋初值
        //加载图片资源设置主角纹理
        Texture image = Resources.Load<Texture>("Image");
        GetComponent<MeshRenderer>().material.mainTexture = image; //动态加载网格渲染器MeshRender
        //根据名称获取身体并设置成黑色
        body = transform.Find("Body");//查找transform的子物体获取body对象
        body.GetComponent<MeshRenderer>().material.color = Color.black;
        //根据名称获取双臂,从而获取两只手臂,都并设置成黑色
        hand = body.Find("Hands");//查找body的子物体获取hand对象,Hands=左手+右手
        BoxCollider[] hands = hand.GetComponentsInChildren<BoxCollider>();
        foreach (var hand in hands)
        {
            hand.GetComponent<MeshRenderer>().material.color = Color.black;
        }
    }
    public float moveSpeed;
    public void Move(float x, float z) //移动方法
    {
        x *= Time.deltaTime * moveSpeed;
        z *= Time.deltaTime * moveSpeed;
        rigid.velocity = new Vector3(x, rigid.velocity.y, z);
    }
     
    public float limit_x, limit_z; //限制X和Z轴上的最大移动距离                                  
    public void PosLimit() //移动位置限制
    {
        Vector3 pos = transform.position;
        if (pos.x < -limit_x)
            pos.x = -limit_x;
        else if (pos.x > limit_x)
            pos.x = limit_x;
        if (pos.z < -limit_z)
            pos.z = -limit_z;
        else if (pos.z > limit_z)
            pos.z = limit_z;
        transform.position = pos;
    }

    public LayerMask layer; //声明一个射线照射层,让射线只能照射到地形  
    public void BodyCharacter()//上身控制
    {
        //身体始终保持在小球上方并且锁定x和z轴的旋转
        body.position = transform.position + Vector3.up;
        body.rotation = new Quaternion(0, body.rotation.y, 0, body.rotation.w);
        //从摄像机发射射线到地面,身体始终朝向照射点
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit; //声明照射点
        if (Physics.Raycast(ray, out hit, 100, layer))
        {
            Debug.DrawLine(Camera.main.transform.position, hit.point, Color.red);
            //获取照射点正上方的坐标,高度同身体一样,让身体朝向该坐标
            Vector3 lookTarget = new Vector3(hit.point.x, body.position.y, hit.point.z);
            body.LookAt(lookTarget);
        }
    }

    public bool stretching = false; //拉伸技能是否激活
    bool stretch = true; //判断伸缩方向,初始为伸展方向    
    public float maxLength; //最大拉伸距离
    public float pullSpeed; //伸缩速度 
    public void Pull() //手臂拉伸
    {
        if (stretching)
        {
            //激活拉伸技能后,手臂变长,达到最大长度则缩短
            Vector3 scale = hand.localScale;
            if (stretch)
                scale.z += Time.deltaTime * pullSpeed;
            else
                scale.z -= Time.deltaTime * pullSpeed;
            //手臂回缩至原有长度,恢复原样,停止拉伸技能
            if (scale.z <= 1)
            {
                scale.z = 1;
                stretching = false;
            }
            //初始状态往前伸展,达到最大长度往回收缩
            if (scale.z == 1)
                stretch = true;
            else if (scale.z >= maxLength)
                stretch = false;
            hand.localScale = scale;
        }
    }

    Transform box; //声明变量接收箱子
    void OnTriggerEnter(Collider other) //触发第一帧
    {
        //如果空着手施放技能时获取碰到的是箱子,获取它
        //之后我们将创建一个Box的脚本挂在箱子身上
        //所以这里根据物体身上是否有Box组件来判断该物体是否为箱子
        if (!box && stretching && other.GetComponent<Box>())
            box = other.transform;
    }
    public void PickUp() //拿起箱子
    {
        //如果获取了箱子,手臂立刻回缩,让箱子身位身体的子物体跟随身体移动
        if (box)
        {
            stretch = false;
            box.parent = body;
            //让被拿取的箱子来到身体前方,并和自己保持同一方向
            Vector3 pos = body.position + body.forward * 2;
            box.position = Vector3.MoveTowards(box.position, pos, Time.deltaTime * pullSpeed);
            box.rotation = Quaternion.Lerp(box.rotation, body.rotation, Time.deltaTime * 5);

        }
    }


    //放下箱子
    public void PutDown()
    {
        //如果手上有箱子,解除父子关系,让box为空
        if (box)
        {
            box.SetParent(null);
            box = null;
        }
    }
}

ColorManage.cs

//ColorManage.cs
using UnityEngine;
/// <summary>
/// 颜色工具类,不用挂
/// </summary>
public class ColorManage
{
    public static Color SetColor(int para) //设置自身颜色
    {
        switch (para) //根据不同参数设置不同颜色
        {
            case 0:
                return Color.red;
            case 1:
                return Color.yellow;
            case 2:
                return Color.blue;
            default:
                return Color.green;
        }
    }
}

Lampstandard.cs

//Lampstandard.cs
using UnityEngine;
/// <summary>
/// 挂所有灯上
/// </summary>
public class Lampstandard : MonoBehaviour
{
    [Range(0, 3)] public int para; //颜色判断参数,范围限定在0~3
    Color color; //初始颜色
    Material material; //声明子物体材质组件
    public bool isBright; //判断灯是否亮起
    void Start()
    {
        //获取初始化颜色
        color = ColorManage.SetColor(para); 
        //自身附上初始化颜色
        GetComponent<MeshRenderer>().material.color = color;
        //获取子物体的材质
        material = transform.GetChild(0).GetComponent<MeshRenderer>().material;
    }
    void OnTriggerEnter(Collider other) //触发
    {
        //如果进入的箱子的颜色和自身拥有的颜色相同,亮灯
        if (other.GetComponent<MeshRenderer>().material.color == color)
        {
            isBright = true;
            material.color = color;
        }
    }
    void OnTriggerExit(Collider other) //离开触发
    {
        //如果离开的箱子的颜色和自身拥有的颜色相同,关灯
        if (other.GetComponent<MeshRenderer>().material.color == color)
        {
            isBright = false;
            material.color = Color.white;
        }
    }
}

LightManage.cs

//LightManage.cs
using UnityEngine;
/// <summary>
/// 挂灯柱管理器上
/// </summary>
public class LightManage : MonoBehaviour
{
    public Lampstandard[] lights; //声明所有灯
    public GameObject againButton; //在编辑器中将按钮物体拖进去
    void Awake()
    {        
        lights = transform.GetComponentsInChildren<Lampstandard>();
        Time.timeScale = 1; //初始时游戏事件为正常值
    }
    void Update()
    {
        //所有灯都亮了,调用过关方法,并暂停游戏
        if (AllLightIsBright())
        {
            againButton.SetActive(true);
            Time.timeScale = 0;
        }
    }
    //判断是否所有的灯都亮了
    bool AllLightIsBright()
    {
        //发现一个灯没亮,立刻返回false,如果都没发现,返回true
        foreach (var light in lights)
        {
            if (!light.isBright)
                return false;
        }
        return true;
    }
}

CameraFollow.cs

//CameraFollow.cs
using UnityEngine;
/// <summary>
/// 挂主摄像机上
/// </summary>
public class CameraFollow : MonoBehaviour
{
    Transform player; //声明主角
    public float height, distance; //和主角在Y轴及Z轴上的距离
    void Start()
    {
        //根据名字获取主角
        player = GameObject.Find("Player").transform; 
    }
    void Update()
    {
        //摄像机始终看向主角
        Quaternion dir = Quaternion.LookRotation(player.position - transform.position);
        transform.rotation = Quaternion.Lerp(transform.rotation, dir, Time.deltaTime);
        //始终在主角身后偏上方位置
        transform.position = player.position + Vector3.up * height + Vector3.back * distance;
    }
}

BottonEvent.cs

//ButtonEvent.cs
using UnityEngine;
using UnityEngine.SceneManagement;
/// <summary>
/// 挂EventSystem上
/// </summary>
public class ButtonEvent: MonoBehaviour
{
    //再来一次
    public void Again()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }
}

Box.cs

//Box.cs
using UnityEngine;
/// <summary>
/// 挂所有箱子上
/// </summary>
public class Box : MonoBehaviour
{
    [Range(0, 3)] public int para; //颜色判断参数
    Rigidbody rigid; //刚体组件
    LightManage lightManage; //灯管理器
    int index; //索引
    void Start()
    {
        //初始化颜色
        GetComponent<MeshRenderer>().material.color = ColorManage.SetColor(para);
        //获取刚体
        rigid = GetComponent<Rigidbody>();
        //获取脚本管理器
        lightManage = FindObjectOfType<LightManage>();
        //给一个随机索引
        index = Random.Range(0, lightManage.lights.Length);
    }
    Transform parent; //声明父物体
    void Update()
    {
        //获取父物体,判断是否被拿起,为空则寻路,不为空取消物理影响
        parent = transform.parent;
        if (!parent)
        {
            Wayfinding();
            rigid.isKinematic = false;
        }
        else
            rigid.isKinematic = true;
    }
    public float moveSpeed; //寻路速度
    public float rotateSpeed; //转身速度
    void Wayfinding() //寻路
    {
        //获取随机一个灯的位置,拿到方向,面向该方向前进
        Vector3 pos = lightManage.lights[index].transform.position;
        Quaternion dir = Quaternion.LookRotation(pos - transform.position);
        transform.rotation = Quaternion.RotateTowards(transform.rotation, dir, rotateSpeed * Time.deltaTime);
        transform.Translate(0, 0, moveSpeed * Time.deltaTime);
        //接近目标索引+1,往下一个灯前进,如果索引超出则为0
        if (Vector3.Distance(transform.position, pos) <= 2)
            index++;
        if (index == lightManage.lights.Length)
            index = 0;
    }
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值