|
先展示一下最后的效果(模型也是Untiy的免费模型)
参加了一个自定义学校的项目,其中有个建造系统需求,所以本着能偷懒就偷懒的原则,第一时间去找有没相关的插件,果然让我找到一个叫(buildSystem)的插件,顾名思义“建造系统”,关键是这插件是免费的!免费!好啦,啥也不说,开整!
就是这个
首先第一时间点开里面的案例(BuildSystem\Example\Scene文件夹) 发现例子还是挺详细的,里面集成了一个背包,具体的使用方法就是先在一个对象上挂一个叫做:ObjectPlacer的脚本,这个脚本是设置哪里是放置区的,里面只需要更改两个地方(选择摄像机,选定哪些层用于放置物品)
实际原理就是摄像机射线,所以这里还有一个Max Plaec Distance的参数
其中Toggle Key用来设置打开背包的按键,默认是E
然后是Object Selector脚本,该脚本用于挂载道具列表以及背包菜单。
先讲这个项目列表,实际就是一个个item的集合(Container),
然后这每个item挂载的是要用来放置的道具,注意这里有两个坑。
1.挂载的如果直接是模型会无法设置这个模型的Layer,所以一般是先创建预制件,这个预制件要设置好Layer,这个层是用来标识这个物品的,方便后续删除物品时用,且要挂载好碰撞盒,因为后续放置物品在该模型上面时就是通过碰撞盒来标识的,如果没有碰撞盒则会穿模
2.这个是item的坑,如果已经把物品挂载在item上了,要修改挂载的物品则最好重新创建一遍,不然无法识别,这应该是一个bug
无法直接改Prefab To Spawn
最后把这些创建好的item挂在ItemList上就完成背包列表了
然后就是创建一个背包菜单预制件了,背包的基本结构是分成Item项目,容器
这是两个预制件,先讲容器
这个背包菜单就是Ui的Canvas,只是我比较喜欢用中文
如图,背包容器有两块是比较重要的,一个就是物品栏的容器,另一个就是关闭菜单的按钮
至于标题栏弄不弄看你,
“菜单背景”这个项挂载的脚本
其中Animator和BuilderUi必须挂载,在动画器里选择
案例里默认创建的那个动画器就好了,然后BuilderUi有三个要填写的项,第一个是用于存放项目的容器,第二个是每个项目的预制件,第三个是关闭菜单按钮的Text(不是挂载按钮,是挂载按钮的那个text),第一个容器
主要是用来遮挡列表的东西,以及提供拖动功能(写个背包的都懂)
“物品容器”挂的重要脚本
然后下面那个容器就单纯用来装到时候实例出来的item
到此,背包的容器项就完成了,接下来的就是单个item(其实就是背包里的一个个格子,动态生成)的预制件,挂载一个Builder Object UI的脚本
如图,只要把自己的这两项挂上就好了
这个预制件实际就是这个背包自动生成格子时会把item的图片和名字挂在这里填写的Text和image上。
到这里背包的预制件就做好了,把它挂在Object Selector脚本上就好了
然后是删除物体的脚本Object Remove,一样挂在控制器上
只需选择摄像机以及需要删除的Layer
下面分享两个控制器,第一个是第一人称的控制脚本(使用了unity的简单控制器组件,且物体挂了个相机为主物体),第二个是上帝视角控制摄像机移动的脚本
public class 角色移动 : MonoBehaviour
{
public float speed = 6.0f;
public float jumpSpeed = 8.0f;
public float gravity = 20.0f;
private Vector3 moveDirection = Vector3.zero;
float RotSpeed = 5f; // camera rotation speed
Transform myTransform;
CharacterController controller;
//cam to rotate
Transform cam;
//max cam angle: from 360 - camAngle to camAngle
float camAngle = 20f; // hal of the camera rotation angle
float vertRot;
public bool stopCamRotation = false;
public bool 隐藏鼠标 = false;
// Start is called before the first frame update
void Start()
{
controller = GetComponent<CharacterController>();
myTransform = transform;
cam = GetComponentInChildren<Camera>().transform;
Cursor.lockState = CursorLockMode.Locked;//锁定指针到视图中心
Cursor.visible = false;//隐藏指针
}
// Update is called once per frame
void Update()
{
PlayerMove();
//视角移动
if (!stopCamRotation)
{
RotateControllerAndCamera();
}
//如果按下背包键
鼠标显示控制();
}
private void 鼠标显示控制()
{
if (Input.GetKeyDown(KeyCode.Q))
{
if (隐藏鼠标)
{
Cursor.lockState = CursorLockMode.Locked;//锁定指针到视图中心
Cursor.visible = false;//隐藏指针
隐藏鼠标 = false;
}
else
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;//显示指针
隐藏鼠标 = true;
}
}
}
private void PlayerMove()
{
CharacterController controller = GetComponent<CharacterController>();
if (controller.isGrounded)
{
moveDirection = new Vector3(Input.GetAxis(&#34;Horizontal&#34;), 0, Input.GetAxis(&#34;Vertical&#34;));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton(&#34;Jump&#34;))
moveDirection.y = jumpSpeed;
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
}
/// <summary>
/// 旋转摄像机
/// </summary>
void RotateControllerAndCamera()
{
//rotare the character horizontally (camera included)
float horRot = Input.GetAxis(&#34;Mouse X&#34;) * RotSpeed;
myTransform.Rotate(0, horRot, 0);
//rotate only the camera vertically
vertRot = -Input.GetAxis(&#34;Mouse Y&#34;) * RotSpeed; //by default mouse Y is inverted so we multiply for -1
if (cam != null)
{
float x = cam.rotation.eulerAngles.x;
if (x >= 360 - camAngle - 1 || x <= camAngle + 1) // add 1 to avoid blocks on approsimative values a bit higher than camAngle
{
x += vertRot;
//lock the camera rotation
if (x > camAngle && x <= 180) x = camAngle;
if (x < 360 - camAngle && x > 180) x = 360 - camAngle;
cam.rotation = Quaternion.Euler(x, cam.rotation.eulerAngles.y, 0); //handle strange mouse position at the begning of the game
}
else cam.rotation = Quaternion.identity;
}
}
}
上帝视角的控制脚本
public class 上帝视角控制 : MonoBehaviour
{
public GameObject mainCamera;//获取摄像机
public float rollAngle = 45;//摄像机倾斜角度
public float height = 40f;//摄像机和地图的高度差
public float moveSpeed = 1.5f;//摄像机移动速度系数
public float zoomSpeed = 5f;//缩放速度系数
public float rotateAngleX = 0;
public float rotateAngleY = 0;
public float rotateSpeed = 5f;//旋转速度系数
Vector3 cameraPos;//摄像机临时坐标
private Vector3 moveDirection = Vector3.zero;
float camAngle = 20f; // 相机的最大旋转角度
float vertRot;
void Start()
{
cameraPos = this.transform.position;
mainCamera.transform.position = cameraPos;
mainCamera.transform.eulerAngles = new Vector3(rollAngle, 0, 0);
}
void Update()
{
//更新摄像机坐标
MoveCamera();
RotateControllerAndCamera();
ZoomCamera();
mainCamera.transform.position = cameraPos;
}
void MoveCamera()
{
moveDirection = new Vector3(Input.GetAxis(&#34;Horizontal&#34;), 0, Input.GetAxis(&#34;Vertical&#34;));
//从局部空间转向世界空间
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= moveSpeed;
cameraPos += moveDirection;
//按下shift加速移动摄像机
if (Input.GetKey(KeyCode.LeftShift))
moveSpeed = 2.5f;
if (Input.GetKeyUp(KeyCode.LeftShift))
moveSpeed = 1.5f;
}
void ZoomCamera()
{
//滚动鼠标滑轮缩放摄像机
if (Input.GetAxis(&#34;Mouse ScrollWheel&#34;) > 0)
{
Vector3 moveDirectionZ = transform.forward;
cameraPos += moveDirectionZ * zoomSpeed;
}
if (Input.GetAxis(&#34;Mouse ScrollWheel&#34;) < 0)
{
Vector3 moveDirectionZ = -transform.forward;
cameraPos += moveDirectionZ * zoomSpeed;
}
}
void RotateControllerAndCamera()
{
if (Input.GetMouseButton(1))
{
//水平旋转相机
float horRot = Input.GetAxis(&#34;Mouse X&#34;) * rotateSpeed;
this.transform.Rotate(0, horRot, 0);
//垂直旋转相机
vertRot = -Input.GetAxis(&#34;Mouse Y&#34;) * rotateSpeed; //默认情况下,鼠标Y是反转的,因此乘以-1
if (mainCamera.transform != null)
{
float x = mainCamera.transform.rotation.eulerAngles.x;
if (x >= 360 - camAngle - 1 || x <= (camAngle + rollAngle) + 1) //加1以避免近似值上的块略高于凸轮角度
{
x += vertRot;
//lock the camera rotation
if (x > (camAngle + rollAngle) && x <= 180) x = (camAngle + rollAngle);
if (x < 360 - camAngle && x > 180) x = 360 - camAngle;
mainCamera.transform.rotation = Quaternion.Euler(x, mainCamera.transform.rotation.eulerAngles.y, 0); //在游戏开始时处理奇怪的鼠标位置
}
else mainCamera.transform.rotation = Quaternion.identity;
}
}
}
} |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|