585
社区成员
发帖
与我相关
我的任务
分享| 这个作业属于哪个课程 | 软件工程-23年春季学期 |
|---|---|
| 这个作业要求在哪里 | 软件工程实践总结&个人技术总结 |
| 这个作业的目标 | 个人技术总结 |
| 其他参考文献 | CSDN、《构建之法》 |
3D游戏中建筑物的建造
作为这次游戏开发团队的一员,负责实现在游戏中对建筑进行建造与显示的功能。
创建建筑放置区域:在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);
// 在这里可以执行其他操作,例如隐藏放置提示、恢复建筑物的透明度等
}
}
}
导入建筑模型:将准备好的建筑模型导入到Unity项目中。确保导入后可以在Unity编辑器中正确显示。
using UnityEngine;
public class BuildingManager : MonoBehaviour
{
public GameObject buildingPrefab; // 建筑预制体
private void Start()
{
// 在合适的位置和时机实例化建筑模型
Instantiate(buildingPrefab, transform.position, transform.rotation);
}
}

实现建筑建造逻辑:编写脚本来实现建筑的建造逻辑。这包括但不限于以下内容:
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;
}
}


建筑模型导入后在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; // 合法
}
}
在这个任务中,我遇到了几个技术难点和问题,但通过仔细分析和解决,我成功地实现了建筑的建造逻辑。以下是我在开发过程中的总结:
总的来说,通过克服技术难点和解决问题,我成功地实现了建筑的建造逻辑,并且在开发过程中不断学习和提升自己的技术能力。这次经历让我更加熟悉了Unity的开发流程,并为未来的游戏开发项目提供了宝贵的经验。