导入场景资源,人物移动蹦跳代码,鼠标上下左右控制旋转,射线射击,怪物复制、销毁与跟踪人物,射击加分
1.场景的导入。点击window>Asset Store进入商店,选择自己需要的资源(这里资源有付费也有免费的,根据个人需要),然后点击添加至我的资源,会弹出一个窗口,点击接受才能用,添加好后有两种选择,选择转到我的资源,就回到个人的资源点,可以看到自己添加的资源;选择在unity中打开,会直接跳转到unity中,会弹出一个对话框,找到自己的资源,然后点击下载,完成后导入(然后就可以搭建场景了)。
2.编写人物移动代码(此次代码是通过查找的方式控制人物移动的,所以说挂在其他物体身上也可以,但是为了符合面向对象思想,还是挂在人物身上比较好)。在此需要给人物加rigidbody和collider(关于collider的形状可以根据人物形状大体选择,点击collider中的edit collider调整碰撞器大小,关于人物的rigidbody的选择如图所示),添加刚体组件是为了让人物不掉下去(目前我只会这样做,但是应该有更好的方法)。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class character : MonoBehaviour
{
// 实现控制物体移动旋转方向
/*c程序逻辑1.先拿到移动对象
* 2.用户按下WASD往前左后右移动(用input实时获取用户的键盘输入,用transform函数实现,以Z轴作为正方)
*/
GameObject onecharacter;//声明变量
public float movespeed = 10f;//控制人物速度,此处速度不合理,public可以在外部调整速度
public float jumpspeed = 10f;//这个是控制人物跳跃大小的
void Start()
{
onecharacter = GameObject.Find("Slime_03 Leaf");//必须和自己场景中的名字一致,从场景中拿到物体
}
void Update()
{
float MoveX = Input.GetAxis("Horizontal");//用户按下A 返回-1 D+1
onecharacter.transform.Translate(new Vector3(MoveX * movespeed * Time.deltaTime,0,0));
float MoveZ = Input.GetAxis("Vertical");//用户按下W 返回+1 S-1
onecharacter.transform.Translate(new Vector3( 0, 0,MoveZ * movespeed * Time.deltaTime));
if(Input .GetKey (KeyCode.Space))
{
onecharacter.transform.Translate(new Vector3(0, 1*jumpspeed , 0)*Time .deltaTime );//人物跳跃
}
}
}
3.编写摄像机跟踪代码(代码赋予摄像机)。这里需要创建两个分物体,放于人物之中其中一个空物体位于人物后上方(跟踪对象),另外一个物品位于人物正前方(视线目标),自己调整好角度。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class camera : MonoBehaviour
{
// 摄像机跟看主角与之一起移动
/*1.在任务中设置一个空物体为摄像机跟踪点
*2.让摄像机坐标与跟踪点坐标一致
*3.平滑计算缓慢跟踪
*/
GameObject Onetarget;//跟踪目标
GameObject Onecamera;//摄像机
GameObject Onerole;//看向目标
public float followtime = 1f;//摄像机平滑移动的时间
void Start()
{
Onetarget = GameObject.Find("follow");
Onecamera = GameObject.Find("Main Camera");
Onerole = GameObject.Find("look");
}
// Update is called once per frame
void Update()
{
Vector3 OneV = Vector3.zero;//初速度
Onecamera.transform.position=Vector3.SmoothDamp(Onecamera.transform.position, Onetarget.transform.position, ref OneV, followtime);//起点,终点,初速度,时间,摄像机起点一直在更新
Onecamera.transform.LookAt(Onerole.transform );//视线所看
}
}
4.编写鼠标滑动控制视角上下左右移动代码(此代码可以给摄像机,也可以给人,我的是给了人物,而且如果摄像机有了固定的目标方向,这个代码那怕是给了摄像机也没有用)。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class rotatecontrol : MonoBehaviour
{
// 通过鼠标上下左右移动控制摄像机或人物上下左右旋转
//1.检测用户是否滑动鼠标 2.如果滑动就旋转X轴和Y轴
float RotionXX;
float RotionYY;
public float rotatespeed = 400f;
void Start()
{
}
void Update()
{
float RotionY = Input.GetAxis("Mouse X");
float RotionX = Input.GetAxis("Mouse Y");
//四元数
RotionXX += -RotionX * Time.deltaTime*rotatespeed ;//变量加等
RotionYY += RotionY * Time.deltaTime* rotatespeed;
RotionXX = Mathf.Clamp(RotionXX, -45f, 45f);//X是上下旋转,限制旋转度数(只有这么点)
this.transform.rotation = Quaternion.Euler(RotionXX, RotionYY, 0);//本身不能加等,但是可以声明变量加等
}
}
5.编写射线射击销毁代码(此代码给人物,并且有跨类访问)。这里除了代码还有一个设计瞄准图层的导入,首先将这个图片导入游戏,点击图片设置Texture Type为Sprite(2D and UI),点击Apply,然后鼠标右键创建UI图片,点击(RawImage),将图片拖入Texture中,以2D模式(更加直观)调整好瞄准点位置。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class rayshot : MonoBehaviour
{
//往屏幕中间发射射线、射击
//1.拿到屏幕中间这个点 2.从摄像机为起点向屏幕中间的方向发射射线 3.销毁对象
Vector3 Oneraypoint;
void Start()
{
Oneraypoint = new Vector3(Screen.width / 2, Screen.height / 2, 0f);//将屏幕中间的点转化为三维坐标
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))//0是左键,1是右键
{
Ray oneRay = Camera.main.ScreenPointToRay(Oneraypoint);//以摄像机为起点
RaycastHit oneMonster;
if (Physics.Raycast(oneRay, out oneMonster))//发射射线,射到物体存入oneMonster
{
Debug.Log("射线射到怪物");
string monsterName = oneMonster.transform.name; //获取射中的怪物名称
if (monsterName == "TurtleShellPBR(Clone)") //判断是否射中的是"monster"怪物,这样写就不会出现拆家问题了
{
Destroy(oneMonster.transform.gameObject); //销毁射中的怪物对象
scoremanger .currentScore += 1; //通知分数管理器类加分,两个类之间相互访问变量
}
}
}
}
}
6.编写怪物克隆代码(此代码给怪物)。(目前来说我的代码有一个bug,会出现怪物在同一地方克隆的问题)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class monstermanager : MonoBehaviour
{
// 1.计时,如果够5秒,就执行一个函数(克隆怪物) 2.怪物克隆时平面坐标随机
float SaveTime = 0f;
GameObject Onemuban;
GameObject Center;
void Start()
{
Onemuban = GameObject.Find("TurtleShellPBR");
Center = GameObject.Find("park_prop04");
}
// Update is called once per frame
void Update()
{
SaveTime += Time.deltaTime;//累计时间
if(SaveTime >=5f)//f的话,不用整数,小数也可以
{
Debug.Log("时间够5秒了,可以刷新了");
CloneMonster();
SaveTime = 0;//到了5秒后重新归0
}
void CloneMonster()//克隆函数
{
float RanX =Center .transform .position .x+ Random.Range(1F, 15F);
float RanY = Center.transform.position.z + Random.Range(1F, 15F);//以...为中心点,方圆地区克隆怪物,这个范围也可以自己设置
Debug.Log("开始克隆");
for(int i = 0; i < 20; i++)//一次克隆20个
{
GameObject TempOBJ = GameObject.Instantiate(Onemuban, new Vector3(RanX, 0, RanY), Quaternion.identity);//克隆怪物
Destroy(TempOBJ, 5f);//后面加上...f意思是几秒后销毁,要是不加会直接销毁
}
}
}
}
7. 编写怪物追踪代码(此代码可以随意给与,我直接给了主角)。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
// 怪物跟踪代码
public GameObject MainRole;
public GameObject Monster;
// Update is called once per frame
void Start()
{
MainRole = GameObject.Find("Slime_03 Leaf");
Monster = GameObject.Find("TurtleShellPBR(Clone)");
}
void Update()
{
Vector3 RoleForwardV = MainRole.transform.forward;
Vector3 RoleTomonsterV = Monster.transform.position - MainRole.transform.position;
float DotResult = Vector3.Dot(RoleForwardV, RoleTomonsterV.normalized);
if (DotResult < 0)
{
Debug.Log("后方");
}
if (DotResult == 0)
{
Debug.Log("侧方");
}
if (DotResult > 0)
{
Debug.Log("前方");
Monster.transform.Translate(-RoleTomonsterV.normalized * Time.deltaTime);//执行追踪
}
}
}
8.编写射击加分代码(此代码还是任意给予)。为了使得分其在屏幕中显示,需要创建一个文本框,并在代码中引用。
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class scoremanger : MonoBehaviour
{
// 射击加分
TMP_Text OneWenBen;
GameObject wenben;
public static int currentScore = 0;//静态的,需在另一个代码中访问它
private void Start()
{
wenben = GameObject.Find("Text (TMP)");//存储文本框
OneWenBen = wenben.GetComponent<TMP_Text>();//获取组件
}
private void LateUpdate()//later是为了让加分发生在碰撞后
{
Debug.Log("恭喜你!得分了!你的分数是:" + currentScore);
OneWenBen.text = "Score:" + currentScore.ToString();//使文本框实时存储分数
}
}
此代码多多少少有一点小问题,后期可能会有细微修改