找回密码
 立即注册
查看: 705|回复: 0

Unity建造系统插件(BuildSystem)使用说明

[复制链接]
发表于 2020-11-25 09:57 | 显示全部楼层 |阅读模式
先展示一下最后的效果(模型也是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("Horizontal"), 0, Input.GetAxis("Vertical"));
            moveDirection = transform.TransformDirection(moveDirection);
            moveDirection *= speed;
            if (Input.GetButton("Jump"))
                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("Mouse X") * RotSpeed;
        myTransform.Rotate(0, horRot, 0);

        //rotate only the camera vertically
        vertRot = -Input.GetAxis("Mouse Y") * 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("Horizontal"), 0, Input.GetAxis("Vertical"));
        //从局部空间转向世界空间
        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("Mouse ScrollWheel") > 0)
        {
            Vector3 moveDirectionZ = transform.forward;
            cameraPos += moveDirectionZ * zoomSpeed;
        }
        if (Input.GetAxis("Mouse ScrollWheel") < 0)
        {
            Vector3 moveDirectionZ = -transform.forward;
            cameraPos += moveDirectionZ * zoomSpeed;
        }

    }

    void RotateControllerAndCamera()
    {
        if (Input.GetMouseButton(1))
        {
            //水平旋转相机
            float horRot = Input.GetAxis("Mouse X") * rotateSpeed;
            this.transform.Rotate(0, horRot, 0);

            //垂直旋转相机
            vertRot = -Input.GetAxis("Mouse Y") * 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;
            }

        }

    }

}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-12-25 15:34 , Processed in 0.164521 second(s), 28 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表