我正在制作一个构建系统,但有 2 行给出了以下错误,我无法修复它。
线路:5+11
private void ghostifyModel(Transform modelParent, Material ghostMaterial = null)
{
if (ghostMaterial != null)
{
foreach(MeshRenderer meshRenderer in modelParent.GetComponentInChildren<MeshRenderer>())
{
meshRenderer.material = ghostMaterial;
}
}else
{
foreach (Collider modelColliders in modelParent.GetComponentInChildren<Collider>())
{
modelColliders.enabled = false;
}
}
}
代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
[Header("Build Objects")]
[SerializeField] private List<GameObject> floorObjects = new List<GameObject>();
[SerializeField] private List<GameObject> wallObjects = new List<GameObject>();
[Header("Build Settings")]
[SerializeField] private SelectedBuildType currentBuildType;
[SerializeField] private LayerMask connecterLayer;
[Header("Ghost Settings")]
[SerializeField] private Material ghostMaterialValid;
[SerializeField] private Material ghostMaterialInvalid;
[SerializeField] private float connectorOverlapRadius = 1;
[SerializeField] private float maxGroundAngle = 45f;
[Header("Internal State")]
[SerializeField] private bool isBuilding = false;
[SerializeField] private int currentBuildingIndex;
private GameObject ghostBuildGameobject;
private bool isGostInvalidPosition = false;
private Transform ModelParent = null;
private void Update()
{
if (Input.GetKeyDown(KeyCode.B))
isBuilding = !isBuilding;
if (isBuilding)
{
ghostBuild();
if (Input.GetMouseButtonDown(0))
placeBuild();
}
else if (ghostBuildGameobject)
{
Destroy(ghostBuildGameobject);
ghostBuildGameobject = null;
}
}
private void ghostBuild()
{
GameObject currentBuild = getCurrentBuild();
createGhostPrefab(currentBuild);
moveGhostPrefabToRaycast();
checkBuildValidity();
}
private void createGhostPrefab(GameObject currentBuild)
{
if (ghostBuildGameobject == null)
{
ghostBuildGameobject = Instantiate(currentBuild);
ModelParent = ghostBuildGameobject.transform.GetChild(0);
ghostifyModel(ModelParent, ghostMaterialValid);
ghostifyModel(ghostBuildGameobject.transform);
}
}
private void moveGhostPrefabToRaycast()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
ghostBuildGameobject.transform.position = hit.point;
}
}
private void checkBuildValidity()
{
Collider[] colliders = Physics.OverlapSphere(ghostBuildGameobject.transform.position, connectorOverlapRadius);
if (colliders.Length > 0)
{
ghostConnectBuild(colliders);
}
else
{
ghostSeperateBuild();
}
}
private void ghostConnectBuild(Collider[] colliders)
{
Connector bestConnector = null;
foreach (Collider collider in colliders)
{
Connector connector = collider.GetComponent<Connector>();
if (connector.canConnectTo)
{
bestConnector = connector;
break;
}
}
if (bestConnector == null || currentBuildType == SelectedBuildType.floor && bestConnector.isConnectedToFloor || currentBuildType == SelectedBuildType.wall && bestConnector.isConnectedToWall)
{
ghostifyModel(ModelParent, ghostMaterialInvalid);
isGostInvalidPosition = false;
return;
}
snapGhostPrefabToConnector(bestConnector);
}
private void snapGhostPrefabToConnector(Connector connector)
{
Transform ghostConnector = findSnapConnecter(connector.transform, ghostBuildGameobject.transform.GetChild(1));
ghostBuildGameobject.transform.position = connector.transform.position - (ghostConnector.position - ghostBuildGameobject.transform.position);
if (currentBuildType == SelectedBuildType.wall)
{
Quaternion newRotation = ghostBuildGameobject.transform.rotation;
newRotation.eulerAngles = new Vector3(newRotation.eulerAngles.x, connector.transform.rotation.eulerAngles.y, newRotation.eulerAngles.z);
ghostBuildGameobject.transform.rotation = newRotation;
}
ghostifyModel(ModelParent, ghostMaterialValid);
isGostInvalidPosition = true;
}
private void ghostSeperateBuild()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (currentBuildType == SelectedBuildType.wall)
{
ghostifyModel(ModelParent, ghostMaterialInvalid);
isGostInvalidPosition = false;
}
if (hit.collider.transform.root.CompareTag("Buildables"))
{
ghostifyModel(ModelParent, ghostMaterialInvalid);
isGostInvalidPosition = false;
}
if (Vector3.Angle(hit.normal, Vector3.up) < maxGroundAngle)
{
ghostifyModel(ModelParent, ghostMaterialValid);
isGostInvalidPosition = true;
}
else
{
ghostifyModel(ModelParent, ghostMaterialInvalid);
isGostInvalidPosition = false;
}
}
}
private Transform findSnapConnecter(Transform snapConnector, Transform ghostConnectorParent)
{
ConnectorPosition OppositeConnectorTag = getOppositePosition(snapConnector.GetComponent<Connector>());
foreach (Connector connector in ghostConnectorParent.GetComponentsInChildren<Connector>())
{
if (connector.connectorPosition == OppositeConnectorTag)
return connector.transform;
}
return null;
}
private ConnectorPosition getOppositePosition(Connector connector)
{
ConnectorPosition position = connector.connectorPosition;
if (currentBuildType == SelectedBuildType.wall && connector.connectorParentType == SelectedBuildType.wall)
return ConnectorPosition.bottom;
if (currentBuildType == SelectedBuildType.floor && connector.connectorParentType == SelectedBuildType.wall && connector.connectorPosition == ConnectorPosition.top)
if (connector.transform.root.rotation.y == 0)
{
return GetConnectorClosestToPlayer(true);
}
else
{
return GetConnectorClosestToPlayer(false);
}
switch (position)
{
case ConnectorPosition.left:
return ConnectorPosition.right;
case ConnectorPosition.right:
return ConnectorPosition.left;
case ConnectorPosition.top:
return ConnectorPosition.bottom;
case ConnectorPosition.bottom:
return ConnectorPosition.top;
default:
return ConnectorPosition.bottom;
}
}
private ConnectorPosition GetConnectorClosestToPlayer(bool topBottom)
{
Transform cameraTransform = Camera.main.transform;
if (topBottom)
{
return cameraTransform.position.z >= ghostBuildGameobject.transform.position.z ? ConnectorPosition.bottom : ConnectorPosition.top;
}
else
return cameraTransform.position.x >= ghostBuildGameobject.transform.position.x ? ConnectorPosition.left : ConnectorPosition.right;
}
private void ghostifyModel(Transform modelParent, Material ghostMaterial = null)
{
if (ghostMaterial != null)
{
foreach(MeshRenderer meshRenderer in modelParent.GetComponentInChildren<MeshRenderer>())
{
meshRenderer.material = ghostMaterial;
}
}else
{
foreach (Collider modelColliders in modelParent.GetComponentInChildren<Collider>())
{
modelColliders.enabled = false;
}
}
}
}
[System.Serializable]
public enum SelectedBuildType
{
floor,
wall,
}
我尝试自己修复它,但我只是从脚本开始,所以我无法弄清楚。
GetComponentInChildren
返回单个项目,而 GetComponentsInChildren
(注意“Components”中的复数“s”)返回枚举。使用后一种方法。