赞
踩
一、鼠标控制视角旋转
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); } } }
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); } }
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); } }
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、创建一个Sphere命名为Fireball
2、修改WanderingAi脚本
3、创建脚本Fireball
让fireball和player之间产生一个碰撞
①勾选Is Trigger
②添加Rigidbody(不勾选Gravity)
七、改为自己也发射火球来攻击Enemy
八、在场景中加入固定的Enemy
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。