当前位置:   article > 正文

unity学习笔记——一个简单的白盒第一人称射击游戏_unity whiteboxing

unity whiteboxing

一、鼠标控制视角旋转
1、首先我们利用unity中的从Cube制作一个简单的迷宫。利用Capsule制作一个简单的角色,并为其添加子物体Camera。
在这里插入图片描述
2、编写脚本MouseLook时视角能够根据鼠标的移动产生相应的旋转。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MouseLook : MonoBehaviour
{
    //定义一个枚举类型
    public enum RotationAxes
    {
        MouseXAndY=0,
        MouseX=1,
        MouseY=2
    }
    public RotationAxes axes = RotationAxes.MouseXAndY;
    //定义旋转的速度参考
    public float sensitivityHor = 9.0f;
    public float sensitivityVert = 5.0f;
    public float minmunVert = -45.0f;
    public float maxmumVert = 45.0f;
    private float _rotationX = 0;
    // Start is called before the first frame update
    void Start()
    {
        //禁止对玩家进行物理旋转
        Rigidbody body = GetComponent<Rigidbody>();
        //检查组件是否存在,存在的话就冻结
        if (body != null)
            body.freezeRotation = true;
    }

    // Update is called once per frame
    void Update()
    {
        //水平滑动鼠标产生左右旋转
        if(axes==RotationAxes.MouseX)
        {
            //旋转与速度相关联,Input是unity调用外部输入设备的一个类
            transform.Rotate(0, Input.GetAxis("Mouse X")*sensitivityHor, 0);
        }
        //垂直滑动鼠标产生上下旋转
        else if(axes==RotationAxes.MouseY)
        {
            _rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert;
            _rotationX = Mathf.Clamp(_rotationX, minmunVert, maxmumVert);//角度限制
            //保持水平旋转不会因为垂直而发生作用
            float rotationY = transform.localEulerAngles.y;
            transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);//欧拉角
        }
        //水平与垂直滑动左右、上下旋转
        else
        {
            //垂直旋转
            _rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert;
            _rotationX = Mathf.Clamp(_rotationX, minmunVert, maxmumVert);//角度限制
            //水平旋转
            float delta = Input.GetAxis("Mouse X") * sensitivityHor;
            float rotationY = transform.localEulerAngles.y + delta;
            //统一到使用欧拉角的方式来实现
            transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

Edit-Project Settings-Input可以看到有关Input在这里插入图片描述
3、脚本绑定
为player和子物体Camera均添加MouseLook脚本,player用于x轴方向控制,Camera用于y轴控制,这样可以避免角色本身产生一些旋转,导致视角旋转不自然。
二、W、A、S、D控制角色移动脚本
1、脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//当你添加的一个用了RequireComponent组件的脚本,需要的组件将会自动被添加到game object(游戏物体)
[RequireComponent(typeof(CharacterController))]
[AddComponentMenu("Control script/FPS Input")]
public class FPSInput : MonoBehaviour
{
    public float speed = 0.05f;
    public float gravity = -9.8f;//重力加速度
    private CharacterController _characterController;//角色控制器,解决穿墙的问题
    // Start is called before the first frame update
    void Start()
    {
        _characterController = GetComponent<CharacterController>();
    }

    // Update is called once per frame
    void Update()
    {
        //固定的向Y轴进行移动
        //transform.Translate(0, speed, 0);
        //Horizontal映射左和右
        float deltaX = Input.GetAxis("Horizontal") * speed;
        //Vertical映射前和后
        float deltaZ = Input.GetAxis("Vertical") * speed;
        Vector3 movement = new Vector3(deltaX, 0, deltaZ);
        //使对角移动的速度和沿轴移动的速度一致
        movement = Vector3.ClampMagnitude(movement, speed);
        //让物体紧紧地贴在地面上走
        movement.y = gravity;
        //引入帧间速率(考虑不同的计算机的处理能力是不一样的,可能在不同的电脑上移动速度不一样),平衡移动,加上*Time.deltaTime
        movement *= Time.deltaTime;
        //使用角色控制器不能使用transform.Translate方法
        //transform.Translate(deltaX*Time.deltaTime, 0, deltaZ*Time.deltaTime);
        //把movement向量从本地坐标系变换为全局坐标系
        movement = transform.TransformDirection(movement);
        //使用角色控制器的通过movement向量移动
        _characterController.Move(movement);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

2、将此脚本绑定到player上面,这样就可以用WASD控制玩家移动了。

三、射击脚本
1、脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RayShooter : MonoBehaviour
{
    private Camera _camera;
    // Start is called before the first frame update
    void Start()
    {
        _camera = GetComponent<Camera>();
        //隐藏光标
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }
    //用GUI Label这个方法绘制一个长和宽为12像素的区域,在此区域上显示符号“*”
    private void OnGUI()
    {
        int size = 12;
        float posX = _camera.pixelWidth / 2 - size / 4;
        float posY = _camera.pixelHeight / 2 - size / 4;
        GUI.Label(new Rect(posX, posY, size, size), "*");
    }
    // Update is called once per frame
    void Update()
    {
        //0代表鼠标左键
        if(Input.GetMouseButtonDown(0))
        {
            //射击的位置
            Vector3 point = new Vector3(_camera.pixelWidth / 2, _camera.pixelHeight / 2, 0);
            //摄像机朝屏幕的正中心产生射线
            Ray ray = _camera.ScreenPointToRay(point);
            //用于保存击中的信息
            RaycastHit hit;
            if(Physics.Raycast(ray,out hit))//保留位置信息
            {
                //Debug.Log("Hit " + hit.point);
                //此句用于控制台输出信息
                //启用协程
                StartCoroutine(SphereIndicator(hit.point));//这个协成方法传递了SphereIndicator这个函数,遇到yield这个关键字停止
            }
        }
    }
    //协程使用方法
    private IEnumerator SphereIndicator(Vector3 pos)
    {
        //由代码产生一个原生对象——球体
        GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        //球体产生的位置
        sphere.transform.position = pos;
        //此球体会在射击位置暂停一秒钟,yield关键词告诉协程在何处暂停
        yield return new WaitForSeconds(1);
        Destroy(sphere);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

2、将RayShooter绑定到player上面
四、可射击对象
1、简单创建一个Cube当做Enemy,此功能实现有很多方法,比如:
①在游戏对象上加一个Tag(Enemy),判断射击是否为Enemy
②用脚本组件代表Enemy这个信息,此脚本组件产生响应
……
2、创建一个脚本ReactiveTarget赋给Enemy
3、改写RayShooter代码
五、自动生成Enemy
1、将Enemy拖动到Prefab文件夹中,成为一个预制体
2、在场景中添加一个空对象,命名为SceneController
3、编写SceneController脚本
Instantiate可以用于子弹的产生,比较适合第三人称的游戏,在同一个位置产生子弹

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SceneController : MonoBehaviour
{
    //SerializeField用于让一个私有对象在检视面板修改参数
    [SerializeField] private GameObject enemyPrefab;
    private GameObject _enemy;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if(_enemy==null)
        {
            //unity中用于创建一个实例
            //调用Instantiate这个方法,生成一个enemyPrefab来付给_enemy
            //可以用于子弹的产生
            //两个游戏对象开始类型不同,所以把enemyPrefab转换成GameObject,跟_enemy类型相同
            _enemy = Instantiate(enemyPrefab) as GameObject;
            _enemy.transform.position = new Vector3(0, 1, 0);
            float angle = Random.Range(0, 360);
            _enemy.transform.Rotate(0, angle, 0);
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

六、敌人反击
1、创建一个Sphere命名为Fireball
2、修改WanderingAi脚本
3、创建脚本Fireball
让fireball和player之间产生一个碰撞
①勾选Is Trigger在这里插入图片描述
②添加Rigidbody(不勾选Gravity)
在这里插入图片描述
七、改为自己也发射火球来攻击Enemy
八、在场景中加入固定的Enemy

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/104140?site
推荐阅读
相关标签
  

闽ICP备14008679号