个人技术总结——Unity3D实现建筑物的建造

222000219潘光耀 2023-06-07 13:30:52
这个作业属于哪个课程软件工程-23年春季学期
这个作业要求在哪里软件工程实践总结&个人技术总结
这个作业的目标个人技术总结
其他参考文献CSDN、《构建之法》

目录

  • 一、技术概述
  • 1.1问题
  • 1.2问题详述
  • 1.3技术难点
  • 二、技术详述
  • 三、技术使用中遇到的问题和解决过程
  • 四、总结
  • 五、参考文献

一、技术概述

1.1问题

3D游戏中建筑物的建造

1.2问题详述

作为这次游戏开发团队的一员,负责实现在游戏中对建筑进行建造与显示的功能。

1.3技术难点

  1. 交互与输入处理:实现建筑放置位置的选择和调整需要处理玩家的交互输入,包括鼠标点击、触摸屏幕等。确保能够准确捕捉和解析用户的输入,以实现建筑的准确放置和调整。
  2. 碰撞检测与遮挡:在建筑建造过程中,需要进行碰撞检测来避免建筑与其他物体发生重叠。确保建筑物与其他场景元素之间进行准确的碰撞检测,并能够遮挡其他对象,以达到真实的建筑效果。
  3. 建筑规则与限制:根据游戏设计,可能会有特定的建筑规则和限制,如建筑的放置范围、相邻建筑的间距要求等。确保在建筑建造过程中对这些规则和限制进行合理的检查和约束,避免不符合规则的建筑出现。
  4. 实时渲染与性能优化:在场景中同时存在多个建筑物时,需要考虑实时渲染的性能问题。确保建筑物的绘制和渲染不会导致游戏的卡顿或性能下降,特别是在移动设备等资源受限的环境中。
  5. 数据管理与持久化:对于建筑建造任务,可能需要进行建筑数据的管理和持久化,以便在游戏保存和加载时能够正确地还原建筑的状态。确保建筑数据的正确保存和读取,以及与其他游戏系统的数据交互。

二、技术详述

  1. 创建建筑放置区域:在Unity中创建一个新的游戏场景或打开现有的场景,作为建筑的放置区域。确保场景的设置和规划符合游戏设计。

    using UnityEngine;
    
    public class BuildingPlacementArea : MonoBehaviour
    {
        // 建筑放置区域的碰撞体
        private BoxCollider placementAreaCollider;
    
        private void Start()
        {
            // 获取或添加建筑放置区域的碰撞体组件
            placementAreaCollider = GetComponent<BoxCollider>();
    
            if (placementAreaCollider == null)
            {
                placementAreaCollider = gameObject.AddComponent<BoxCollider>();
            }
    
            // 设置建筑放置区域的大小和位置
            placementAreaCollider.size = new Vector3(10f, 0.2f, 10f);
            placementAreaCollider.center = Vector3.zero;
    
            // 设置碰撞体为触发器
            placementAreaCollider.isTrigger = true;
        }
    
        // 当有建筑物进入建筑放置区域时调用
        private void OnTriggerEnter(Collider other)
        {
            Building building = other.GetComponent<Building>();
    
            if (building != null)
            {
                // 将建筑物标记为可以放置状态
                building.SetPlacementStatus(true);
    
                // 在这里可以执行其他操作,例如显示放置提示、调整建筑物的透明度等
            }
        }
    
        // 当有建筑物离开建筑放置区域时调用
        private void OnTriggerExit(Collider other)
        {
            Building building = other.GetComponent<Building>();
    
            if (building != null)
            {
                Building building = other.GetComponent<Building>();
            }
            if (building != null)
            {
                // 将建筑物标记为不可放置状态
                building.SetPlacementStatus(false);
    
                // 在这里可以执行其他操作,例如隐藏放置提示、恢复建筑物的透明度等
            }
        }
    }
    
  2. 导入建筑模型:将准备好的建筑模型导入到Unity项目中。确保导入后可以在Unity编辑器中正确显示。

    using UnityEngine;
    
    public class BuildingManager : MonoBehaviour
    {
        public GameObject buildingPrefab; // 建筑预制体
    
        private void Start()
        {
            // 在合适的位置和时机实例化建筑模型
            Instantiate(buildingPrefab, transform.position, transform.rotation);
        }
    }
    

img

  1. 实现建筑建造逻辑:编写脚本来实现建筑的建造逻辑。这包括但不限于以下内容:

    • 在场景中选择建筑位置:允许玩家在场景中选择建筑的放置位置。
    • 检查合法性:确保所选的位置符合建筑的建造规则,如不与其他建筑重叠、不超出地图边界等。
    • 创建建筑对象:在所选位置创建建筑对象,并将其添加到场景中。
    • 调整建筑属性:根据需要,允许玩家对建筑进行调整,如旋转、缩放等。
    using UnityEngine;
    
    public class BuildingManager : MonoBehaviour
    {
        public GameObject buildingPrefab; // 建筑预制体
        public LayerMask buildingMask; // 建筑所在的图层
    
        private GameObject currentBuilding; // 当前正在建造的建筑
    
        private void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                // 检查是否点击到合适的建筑位置
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit;
    
                if (Physics.Raycast(ray, out hit, Mathf.Infinity, buildingMask))
                {
                    // 检查合法性,如位置是否可用等
                    if (CanPlaceBuilding(hit.point))
                    {
                        // 创建建筑对象
                        currentBuilding = Instantiate(buildingPrefab, hit.point, Quaternion.identity);
                    }
                }
            }
            else if (Input.GetMouseButton(1))
            {
                // 取消建造,销毁当前正在建造的建筑
                if (currentBuilding != null)
                {
                    Destroy(currentBuilding);
                    currentBuilding = null;
                }
            }
        }
    
        private bool CanPlaceBuilding(Vector3 position)
        {
            // 在此编写合法性检查的逻辑,例如检查是否与其他建筑重叠、是否超出地图边界等
            // 如果符合建造规则,返回 true;否则返回 false
    
            // 示例:检查是否与其他建筑重叠
            Collider[] colliders = Physics.OverlapSphere(position, buildingPrefab.transform.localScale.x / 2f);
            foreach (Collider collider in colliders)
            {
                if (collider.CompareTag("Building"))
                {
                    return false;
                }
            }
    
            // 检查通过,可以建造
            return true;
        }
    }
    

img

img

三、技术使用中遇到的问题和解决过程

  • 建筑模型导入后在Unity编辑器中显示异常

    • 问题描述:建筑模型导入后在Unity编辑器中显示异常
    • 解决过程:我首先检查了模型文件的格式和内容是否正确,并确保纹理和材质文件也正确导入。然后,我尝试重新导入模型,并在导入选项中调整设置,例如重新计算法线和切线等。最后,我在Unity编辑器中对导入的模型进行了检查,以确保它们在场景中正确显示。
    using UnityEngine;
    
    public class BuildingManager : MonoBehaviour
    {
        public GameObject buildingPrefab; // 建筑预制体
        public Transform buildingPlacementArea; // 建筑放置区域
    
        private GameObject currentBuilding; // 当前建筑对象
    
        void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                // 获取鼠标点击的位置
                Vector3 mousePosition = Input.mousePosition;
                Ray ray = Camera.main.ScreenPointToRay(mousePosition);
                RaycastHit hit;
    
                if (Physics.Raycast(ray, out hit))
                {
                    // 确保点击的位置在建筑放置区域内
                    if (hit.collider.transform == buildingPlacementArea)
                    {
                        // 检查是否已经存在建筑对象,如果存在则销毁
                        if (currentBuilding != null)
                        {
                            Destroy(currentBuilding);
                        }
    
                        // 在点击位置创建建筑对象
                        currentBuilding = Instantiate(buildingPrefab, hit.point, Quaternion.identity);
                    }
                }
            }
        }
    }
    
  • 建筑放置位置的合法性检查不准确

    • 问题描述:在合法性检查中,我遇到了一些问题,例如建筑物重叠检查不准确或边界检查错误。
    • 解决过程:为了解决这个问题,我仔细检查了合法性检查的代码逻辑,并使用调试工具来观察建筑物的碰撞和位置信息。我进行了一些调整,如调整碰撞器的大小和位置,改进碰撞检测算法,确保建筑物在放置时不会重叠,并且不会超出场景的边界。
    using UnityEngine;
    
    public class BuildingManager : MonoBehaviour
    {
        public GameObject buildingPrefab; // 建筑预制体
        public Transform buildingPlacementArea; // 建筑放置区域
    
        private GameObject currentBuilding; // 当前建筑对象
        private Collider currentBuildingCollider; // 当前建筑的碰撞器
    
        void Start()
        {
            currentBuildingCollider = buildingPrefab.GetComponent<Collider>();
        }
    
        void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                // 获取鼠标点击的位置
                Vector3 mousePosition = Input.mousePosition;
                Ray ray = Camera.main.ScreenPointToRay(mousePosition);
                RaycastHit hit;
    
                if (Physics.Raycast(ray, out hit))
                {
                    // 确保点击的位置在建筑放置区域内
                    if (hit.collider.transform == buildingPlacementArea)
                    {
                        // 检查是否已经存在建筑对象,如果存在则销毁
                        if (currentBuilding != null)
                        {
                            Destroy(currentBuilding);
                        }
    
                        // 在点击位置创建建筑对象
                        currentBuilding = Instantiate(buildingPrefab, hit.point, Quaternion.identity);
    
                        // 检查建筑放置的合法性
                        if (IsPlacementValid())
                        {
                            // 合法,可以放置建筑
                            // 执行放置建筑的逻辑
                        }
                        else
                        {
                            // 不合法,无法放置建筑
                            // 执行错误提示或其他处理逻辑
                        }
                    }
                }
            }
        }
    
        bool IsPlacementValid()
        {
            // 检查建筑物是否与其他建筑物重叠
            Collider[] colliders = Physics.OverlapBox(currentBuildingCollider.bounds.center, currentBuildingCollider.bounds.extents, currentBuilding.transform.rotation);
            foreach (Collider collider in colliders)
            {
                if (collider != currentBuildingCollider && collider.CompareTag("Building"))
                {
                    // 发现重叠的建筑物,不合法
                    return false;
                }
            }
    
            // 检查建筑物是否超出边界
            // 根据场景边界的逻辑进行检查,确保建筑物不会超出边界
    
            return true; // 合法
        }
    }
    

四、总结

在这个任务中,我遇到了几个技术难点和问题,但通过仔细分析和解决,我成功地实现了建筑的建造逻辑。以下是我在开发过程中的总结:

  1. 建筑模型导入:在导入建筑模型时,我确保了模型文件的正确性,并通过调整导入选项来解决模型在Unity编辑器中显示异常的问题。
  2. 建筑放置位置的合法性检查:我遇到了建筑放置位置合法性检查不准确的问题。通过检查代码逻辑、调试碰撞和位置信息,我调整了碰撞器的大小和位置,并改进了碰撞检测算法,确保建筑物在放置时不会重叠,并且不会超出场景边界。
  3. 代码实现建筑建造逻辑:我编写了脚本来实现建筑的建造逻辑,包括允许玩家选择建筑位置、检查合法性、创建建筑对象以及对建筑属性的调整。通过逐步实现这些功能,我成功地实现了建筑的建造逻辑。
  4. 解决技术问题的过程:在遇到问题时,我采取了系统的解决过程。首先,我仔细检查了代码和资源文件,确保它们的正确性。然后,我使用调试工具来观察和分析问题,以定位并解决其中的错误。最后,我进行了适当的调整和改进,确保功能的正确实现。
  5. 学习与提升:在解决问题的过程中,我积累了宝贵的经验,并学习了如何应对类似的技术难题。通过这次项目,我进一步提升了对Unity开发的理解和技能,为以后的项目开发打下了坚实的基础。

总的来说,通过克服技术难点和解决问题,我成功地实现了建筑的建造逻辑,并且在开发过程中不断学习和提升自己的技术能力。这次经历让我更加熟悉了Unity的开发流程,并为未来的游戏开发项目提供了宝贵的经验。

五、参考文献

Microsoft. "C# Coding Conventions"

Unity Technologies官方的《Unity Coding Standards》

...全文
1544 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

585

社区成员

发帖
与我相关
我的任务
社区描述
软件工程-2022-23学年(第二学期)
软件工程 高校
社区管理员
  • LinQF39
  • promisekoloer
  • 异梦1
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧