Unity
网络游戏黑暗之光笔记
第三章 创建游戏运行场景及角色控制
1. 创建场景导入资源等
2. 标签管理
- 使用标签来进行判定,使用const减少代码的出错率
//地面标签 public const string ground = "Ground";//const 标明这个是一个共有的不可变的变量 //玩家标签 public const string player = "Player";
3. 鼠标控制人物移动
鼠标点击地面特效,在角色上挂载脚本脚本
public GameObject effect_click_prefab; void Update() { //检测鼠标的按下 //将鼠标的坐标转换为射线该 //射线与地面发生碰撞返回发生碰撞的点,然后让角色转向该点,开始移动。当移动到一定范围时停止移动。 if (Input.GetMouseButtonDown(0)) { Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition); //保存碰撞信息 RaycastHit hitInfo; bool isCollider = Physics.Raycast(ray, out hitInfo); if(isCollider&& hitInfo.collider.tag ==Tags.ground) { //实例化点击的效果 showClickEffect(hitInfo.point); } } void showClickEffect(Vector3 hitPoint) { hitPoint = new Vector3(hitPoint.x, hitPoint.y+0.1f,hitPoint.z); GameObject.Instantiate(effect_click_prefab, hitPoint, Quaternion.identity); } }
- 控制主角的朝向(鼠标点击地面的时候转向)
增加两个对象
private Vector3 targetPosition = Vector3.zero; private bool isMoving = false;//表示鼠标是否按下
在update方法的 if(isCollider&& hitInfo.collider.tag ==Tags.ground)中增加
isMoving = true; LookAtTarget(hitInfo.point);
在update方法中增加两个判定语句
if (Input.GetMouseButtonUp(0)) { isMoving = false; } if (isMoving) { //得到要移动的目标位置 //让主角朝向目标位置 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hitInfo; bool isCollider = Physics.Raycast(ray, out hitInfo); if (isCollider && hitInfo.collider.tag == Tags.ground) { LookAtTarget(hitInfo.point); } }
增加一个lookat方法
void LookAtTarget(Vector3 hitPoint) { targetPosition = hitPoint; targetPosition = new Vector3(targetPosition.x, transform.position.y, targetPosition.z); this.transform.LookAt(targetPosition); }
- 控制主角的移动,添PlayerMove脚本挂载到角色上
默认值是当前位置不会在游戏一开始时就运行在PlayDir脚本Start函数中添加
targetPosition = transform.position;
public float speed = 4; private PlayerDir dir; private CharacterController controller; void Start() { dir = this.GetComponent<PlayerDir>(); controller = this.GetComponent<CharacterController>(); } void Update() { float distance = Vector3.Distance(dir.targetPosition, transform.position); if (distance > 0.3f) { isMoving = true; //state = PlayerState.Moving; controller.SimpleMove(transform.forward * speed); } }
添加人物动画
控制人物动画播放的脚本
using UnityEngine; using System.Collections; public class PlayerAnimation : MonoBehaviour { private PlayerMove move; void Start() { move = this.GetComponent<PlayerMove>(); } void LateUpdate() { if (move.state == PlayerState.Moving) { PlayAnim("Run"); } else if (move.state == PlayerState.Idle) { PlayAnim("Idle"); } } void PlayAnim(string animName) { GetComponent<Animation>().CrossFade(animName); } }
注意在void PlayAnim方法中教程中使用的旧版的代码,新版的代码为
GetComponent<Animation>().CrossFade(animName);
- 完善的PlayerDir代码
public class PlayerDir : MonoBehaviour { public GameObject effect_click_prefab; public Vector3 targetPosition = Vector3.zero; private PlayerMove playerMove; private bool isMoving = false;//表示鼠标是否按下 private void Start() { //默认值是当前位置不会在游戏一开始时就运行 targetPosition = transform.position; playerMove = this.GetComponent<PlayerMove>(); } void Update() { if (Input.GetMouseButtonDown(0)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hitInfo; bool isCollider = Physics.Raycast(ray, out hitInfo); if (isCollider && hitInfo.collider.tag == Tags.ground) { isMoving = true; ShowClickEffect(hitInfo.point); LookAtTarget(hitInfo.point); } } if (Input.GetMouseButtonUp(0)) { isMoving = false; } if (isMoving) { //得到要移动的目标位置 //让主角朝向目标位置 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hitInfo; bool isCollider = Physics.Raycast(ray, out hitInfo); if (isCollider && hitInfo.collider.tag == Tags.ground) { LookAtTarget(hitInfo.point); } } else { if (playerMove.isMoving) { LookAtTarget(targetPosition); } } } //实例化出来点击的效果 void ShowClickEffect(Vector3 hitPoint) { hitPoint = new Vector3(hitPoint.x, hitPoint.y + 0.1f, hitPoint.z); GameObject.Instantiate(effect_click_prefab, hitPoint, Quaternion.identity); } //让主角朝向目标位置 void LookAtTarget(Vector3 hitPoint) { targetPosition = hitPoint; targetPosition = new Vector3(targetPosition.x, transform.position.y, targetPosition.z); this.transform.LookAt(targetPosition); } }
4. 控制相机跟随主角的移动
- 在主摄像机挂在FollowCamera脚本
private Transform player; private Vector3 offsetPosition;//位置偏移 void Start() { player = GameObject.FindGameObjectWithTag(Tags.player).transform; //使相机永远朝向主角 transform.LookAt(player.position); offsetPosition = transform.position - player.position; } void Update() { transform.position = offsetPosition + player.position; }
- 使用鼠标滑动控制相机视野的拉近和拉远
定义一个 public float scrollSpeed = 10;
在上面的Update方法中增加 ScrollView();
方法
void ScrollView() { //print(Input.GetAxis("Mouse ScrollWheel"));//向后 返回负值 (拉近视野) 向前滑动 返回正值(拉远视野) distance = offsetPosition.magnitude; //获取鼠标中键的值 distance += Input.GetAxis("Mouse ScrollWheel") *- scrollSpeed; distance = Mathf.Clamp(distance, 2, 18); offsetPosition = offsetPosition.normalized * distance; }
注意要在distance += Input.GetAxis("Mouse ScrollWheel") *- scrollSpeed;
中的
- scrollSpeed负号,才是与实际效果一致
- 相机距离的限制
distance = Mathf.Clamp(distance, 2, 18);
- 相机的旋转
void RotateView() { //Input.GetAxis("Mouse X");//得到鼠标在水平方向的滑动 //Input.GetAxis("Mouse Y");//得到鼠标在垂直方向的滑动 if (Input.GetMouseButtonDown(1)) { isRotating = true; } if (Input.GetMouseButtonUp(1)) { isRotating = false; } if (isRotating) { transform.RotateAround(player.position, player.up, rotateSpeed * Input.GetAxis("Mouse X")); Vector3 originalPos = transform.position; Quaternion originalRotation = transform.rotation; transform.RotateAround(player.position, transform.right, -rotateSpeed * Input.GetAxis("Mouse Y"));//影响的属性有两个 一个是position 一个是rotation float x = transform.eulerAngles.x; if (x < 10 || x > 80) {//当超出范围之后,我们将属性归位原来的,就是让旋转无效 transform.position = originalPos; transform.rotation = originalRotation; } } offsetPosition = transform.position - player.position; }
注意方向函数的符号,还有update方法中调用的顺序
限定旋转的方向
float x = transform.eulerAngles.x; if (x < 10 || x > 80) {//当超出范围之后,我们将属性归位原来的,就是让旋转无效 transform.position = originalPos; transform.rotation = originalRotation; }
5. 增加角色状态信息
给角色添加playerstatus脚本
public int grade = 1; public int hp = 100; public int mp = 100; public int coin = 200;//金币数量 public int attack = 20; public int attack_plus = 0; public int def = 20; public int def_plus = 0; public int speed = 20; public int speed_plus = 0; public int point_remain = 0;//剩余的点数