MMORPG游戏开发实战(一)
2019-01-20 本文已影响27人
元宇宙协会
- 新建目录工程
关于工程的文件夹创建
- 代码注释修改
可以百度,这种代码不需要记忆。一大堆,直接用就可以
using System;
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEditor;
public class ScriptsCreat : UnityEditor.AssetModificationProcessor
{
public static void OnWillCreateAsset(string path)
{
path = path.Replace(".meta", "");
if (!path.EndsWith(".cs")) return;
string allText = "// ========================================================\r\n"
+ "// 描述:\r\n"
+ "// 作者:雷潮 \r\n"
+ "// 创建时间:#CreateTime#\r\n"
+ "// 版 本:1.0\r\n"
+ "//========================================================\r\n";
allText += File.ReadAllText(path);
allText = allText.Replace("#CreateTime#", System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
File.WriteAllText(path, allText);
AssetDatabase.Refresh();
}
}
效果:每次创建脚本都会有自己的代码注释
效果图- 使用角色控制器进行移动
游戏开发中,Boss与主角的移动都是通过角色控制器进行的
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RoleCtrl : MonoBehaviour {
private CharacterController c;
private Vector3 hitPoint = Vector3.zero; // 目标点
private float speed = 10f;
private Quaternion m_rotation;
//旋转速度
private float r_speed = 0.2f;
private bool isRotationOver = false;
void Start () {
c = GetComponent<CharacterController>();
}
void Update () {
if (c == null) return;
//点击屏幕
if (Input.GetMouseButtonUp(0)) //
{
Debug.Log("鼠标点击屏幕");
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
// 如果碰到了地面,会得到一个点
if (hitInfo.collider.gameObject.name.Equals("Ground", System.StringComparison.CurrentCultureIgnoreCase))
{
hitPoint = hitInfo.point;
isRotationOver = false;
r_speed = 0;
}
}
}
// 如果没有与地面连接,让角色贴着地面
if (!c.isGrounded)
{
c.Move(transform.position + new Vector3(0,-1000,0) - transform.position);
}
if (hitPoint != Vector3.zero)
{
//Debug.DrawLine(Camera.main.transform.position,hitPoint);
// 知识点:为什么要判断大于0.1因为移动过程数值中会出现小数。
if (Vector3.Distance(transform.position,hitPoint) > 0.1)
{
//transform.LookAt(hitPoint); // 朝向目标位置,一方面可以进行相关的操作,一方面可以达到某个位置后运动停止,
//transform.Translate(Vector3.forward*Time.deltaTime*speed,Space.Self);
Vector3 direction = hitPoint - transform.position;
direction = direction.normalized; // 归一化,让其在xyz上的值都为1
direction = direction * Time.deltaTime * speed;
direction.y = 0;
// 让角色朝向目标点
// transform.LookAt(new Vector3(hitPoint.x,transform.position.y,hitPoint.z));
if (!isRotationOver)
{
r_speed += 5f;
// 让角色缓慢转身
m_rotation = Quaternion.LookRotation(direction);
transform.rotation = Quaternion.Lerp(transform.rotation, m_rotation, Time.deltaTime * r_speed);
if (Quaternion.Angle(m_rotation, transform.rotation) < 1f)
{
r_speed = 1;
isRotationOver = true;
}
}
c.Move(direction);
}
}
}
}
using UnityEngine;
public class RoleCtrl : MonoBehaviour {
private CharacterController c;
private Vector3 hitPoint = Vector3.zero; // 目标点
private float speed = 10f;
private Quaternion m_rotation;
//旋转速度
private float r_speed = 0.2f;
void Start () {
c = GetComponent<CharacterController>();
}
void Update () {
if (c == null) return;
//点击屏幕
if (Input.GetMouseButtonUp(0))
{
Debug.Log("鼠标点击屏幕");
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
// 如果碰到了地面,会得到一个点
if (hitInfo.collider.gameObject.name.Equals("Ground", System.StringComparison.CurrentCultureIgnoreCase))
{
hitPoint = hitInfo.point;
r_speed = 0;
}
}
}
// 如果没有与地面连接,让角色贴着地面
if (!c.isGrounded)
{
c.Move(transform.position + new Vector3(0,-1000,0) - transform.position);
}
if (hitPoint != Vector3.zero)
{
// 知识点:为什么要判断大于0.1因为移动过程数值中会出现小数。
if (Vector3.Distance(transform.position,hitPoint) > 0.1)
{
Vector3 direction = hitPoint - transform.position;
direction = direction.normalized; // 归一化,让其在xyz上的值都为1
direction = direction * Time.deltaTime * speed;
direction.y = 0;
// 让角色朝向目标点
// transform.LookAt(new Vector3(hitPoint.x,transform.position.y,hitPoint.z));
if (r_speed <= 1)
{
r_speed += 5f * Time.deltaTime;
// 让角色缓慢转身
m_rotation = Quaternion.LookRotation(direction);
transform.rotation = Quaternion.Lerp(transform.rotation, m_rotation, r_speed);
}
c.Move(direction);
}
}
}
}
- 射线检测
利用射线检测周围的怪物与拾取物体
什么是射线
检测箱子,可以使用射线方式进行
if (Input.GetMouseButtonUp(1))
{
//Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//RaycastHit hit;
//// 发射射线,检测名称为Item的layer层。
//if (Physics.Raycast(ray, out hit, Mathf.Infinity, 1 << LayerMask.NameToLayer("Box")))
//{
// Debug.Log("find box" + hit.collider.name);
//}
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit[] hitArray = Physics.RaycastAll(ray,Mathf.Infinity,1<<LayerMask.NameToLayer("Box"));
if (hitArray.Length > 0)
{
for (int i = 0; i < hitArray.Length; i++)
{
Debug.Log(hitArray[i].collider.name);
}
}
}
Box检测
检测条件:
(1) - 物体的layer在检测的层中
(2) - 物体身上要有碰撞器 (勾选Trigger触发模式,也可以检测)
注意:
当检测的物体重合,也是可以检测到的,射线具备穿透功能
if (Input.GetMouseButtonUp(1))
{
Collider[] cs = Physics.OverlapSphere(this.transform.position, 3, 1 << LayerMask.NameToLayer("Box"));
for (int i = 0; i < cs.Length; i++)
{
Debug.Log(cs[i].name);
}
}
private void OnDrawGizmos()
{
Gizmos.DrawWireSphere(this.transform.position, 3);
}
OnDrawGizmos
检测到Box
触发销毁
using UnityEngine;
public class ScenneCtrl : MonoBehaviour {
[SerializeField]
private Transform transBox;
[SerializeField]
private Transform parentBox;
private GameObject boxPrefab;
private int minCount = 0;
private int maxCount = 10;
private float nextCloneTime = 0;
// 数据存储
private string boxKey = "BoxKey";
private int getBoxCount;
void Start () {
boxPrefab = Resources.Load("BoxPrefabs/Box") as GameObject;
getBoxCount = PlayerPrefs.GetInt(boxKey,0);
}
// Update is called once per frame
void Update () {
if (minCount < maxCount)
{
if (Time.time > nextCloneTime)
{
nextCloneTime = Time.time + 3f;
GameObject cloneObj = Instantiate(boxPrefab);
cloneObj.transform.parent = parentBox;
cloneObj.transform.position = transBox.TransformPoint(new Vector3(UnityEngine.Random.Range(-0.5f,0.5f),0, UnityEngine.Random.Range(-0.5f, 0.5f)));
BoxController box = cloneObj.GetComponent<BoxController>();
if (box != null)
{
box.OnHit = OnHit;
minCount++;
}
}
}
}
private void OnHit(GameObject obj)
{
minCount--;
getBoxCount++;
PlayerPrefs.SetInt(boxKey, getBoxCount);
GameObject.Destroy(obj);
Debug.Log("拾取了" + getBoxCount + "个箱子");
}
}
箱子的代码设置委托,传递自己被点击信息
public class BoxController : MonoBehaviour {
public System.Action<GameObject> OnHit;
public void Hit()
{
if (OnHit != null)
{
OnHit(gameObject);
}
}
}
销毁箱子代码
if (Input.GetMouseButtonUp(1))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
// 发射射线,检测名称为Item的layer层。
if (Physics.Raycast(ray, out hit, Mathf.Infinity, 1 << LayerMask.NameToLayer("Box")))
{
BoxController box = hit.collider.GetComponent<BoxController>();
if (box != null)
{
box.Hit();
}
Debug.Log("find box" + hit.collider.name);
}
简单实用
- NGUI使用