C# 如何根据选中的真/假门位置移动场景视图摄影机?
此脚本附加到每个门,并根据编辑器中的状态更改门的红色或绿色。如果在编辑器中我取消选中/选中门的复选框,它将更改门的颜色和锁定状态: 该脚本具有[ExecuteAlways]属性,因此我也可以在编辑器模式下更改门的锁定状态和颜色C# 如何根据选中的真/假门位置移动场景视图摄影机?,c#,unity3d,C#,Unity3d,此脚本附加到每个门,并根据编辑器中的状态更改门的红色或绿色。如果在编辑器中我取消选中/选中门的复选框,它将更改门的颜色和锁定状态: 该脚本具有[ExecuteAlways]属性,因此我也可以在编辑器模式下更改门的锁定状态和颜色 using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Linq; using System; [ExecuteAlways] public
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System;
[ExecuteAlways]
public class HoriDoorManager : MonoBehaviour
{
public List<DoorHori> doors = new List<DoorHori>();
public bool doorLockState;
private void Awake()
{
if (transform.parent != null)
{
Transform parent = transform.parent;
var children = parent.GetComponentsInChildren<Transform>();
if (children != null)
{
foreach (Transform door in children)
{
if (door.name == "Door_Left" || door.name == "Door_Right")
doors.Add(door.GetComponent<DoorHori>());
}
}
ColorDoors(Color.red, Color.green, doorLockState);
}
}
void OnTriggerEnter()
{
if (doorLockState == false)
{
if (doors != null)
{
for (int i = 0; i < doors.Count; i++)
{
doors[i].OpenDoor();
}
}
}
}
private void Update()
{
ColorDoors(Color.red, Color.green, doorLockState);
}
private void ColorDoors(Color red, Color green, bool state)
{
List<Transform> children = new List<Transform>();
for (int i = 0; i < doors.Count; i++)
{
foreach (Transform child in doors[i].GetComponentsInChildren<Transform>())
{
if (child == doors[i].transform)
continue;
var renderer = child.GetComponent<Renderer>();
renderer.material.shader = Shader.Find("Unlit/ShieldFX");
if (state == true)
{
renderer.material.SetColor("_MainColor", red);
LockState(true);
}
else
{
renderer.material.SetColor("_MainColor", green);
LockState(false);
}
}
}
}
public bool GetLockState
{
get { return doorLockState; }
set { doorLockState = value; }
}
private void LockState(bool state)
{
var collider = gameObject.GetComponent<BoxCollider>();
if (state == false)
{
collider.size = new Vector3(2.3f, 2.736307f, 2.5f);
collider.center = new Vector3(0, 1.378154f, 0);
collider.transform.localPosition = new Vector3(-1.57f, 0, -2.98f);
collider.isTrigger = true;
}
else
{
collider.size = new Vector3(2.3f, 2.736307f, 3);
collider.center = new Vector3(0, 1.378154f, 0);
collider.transform.localPosition = new Vector3(-1.57f, 0, -2.98f);
collider.isTrigger = false;
}
}
}
这是doors状态编辑器的屏幕截图:
现在我要做的是,每次我在编辑器中更改一个门锁定状态时,移动场景视图摄影机,并将其放置在更改的门状态前方一定距离处,以便我可以看到门位置区域
我想制作一张我所有场景视图或太空船的地图,然后指出除了颜色以外,所有的门可能是怎样的
但这里的想法是将场景视图摄影机快速移动到已更改的锁定状态门位置,而不是每次使用鼠标移动。
这样,我可以看到每个门的位置区域,并决定如何在游戏中使用它以后
站在门前的摄像头示例。但现在我需要每次用鼠标移动,找到我更改的门的锁状态。我想让摄像机自动移到门口
或者,也许有一个很好的方法来绘制/创建一个地图,不是迷你地图,而是一个可以在编辑器模式下工作的地图,这样我就可以看到门的位置和颜色,可能是二维的 我想到的一种方法是制作一个脚本,可以附加到门上,找到感兴趣的摄影机,记录其当前位置/旋转,锁定角色使其不移动,然后将摄影机插入到门位置的某个偏移位置,以显示门状态的变化,最后插值回摄像机的初始位置。我想到的一种方法是制作一个脚本,可以附加到门上,找到感兴趣的摄像机,记录其当前位置/旋转,锁定角色,使其不移动,然后将摄影机插值到门位置的某个偏移以显示门状态更改,最后插值回摄影机的初始位置。
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class DoorsLockManager : MonoBehaviour
{
[HideInInspector]
public List<HoriDoorManager> Doors = new List<HoriDoorManager>();
// The global state
[SerializeField] private bool _globalLockState;
// During runtime use a property instead
public bool GlobalLockState
{
get { return _globalLockState; }
set
{
_globalLockState = value;
// apply it to all doors
foreach (var door in Doors)
{
// now you would need it public again
// or use the public property you had there
door.doorLockState = _globalLockState;
}
}
}
private void Awake()
{
var doors = GameObject.FindGameObjectsWithTag("Door");
Doors = new HoriDoorManager[doors.Length].ToList();
for (int i = 0; i < doors.Length; i++)
{
Doors[i] = doors[i].GetComponent<HoriDoorManager>();
}
}
}
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(DoorsLockManager))]
public class DoorsLockManagerEditor : Editor
{
private SerializedProperty _doors;
private SerializedProperty _globalLockState;
private bool shouldOverwrite;
private void OnEnable()
{
_doors = serializedObject.FindProperty("Doors");
_globalLockState = serializedObject.FindProperty("_globalLockState");
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
shouldOverwrite = false;
// Begin a change check here
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(_globalLockState);
if (EditorGUI.EndChangeCheck())
{
// overwrite only once if changed
shouldOverwrite = true;
}
for (int i = 0; i < _doors.arraySize; i++)
{
var door = _doors.GetArrayElementAtIndex(i);
// if door == null the script itself has an error since it can't even find the SerializedProperty
if (door == null)
{
EditorGUILayout.HelpBox("There was an error in the editor script!\nPlease check the log", MessageType.Error);
Debug.LogError("Couldn't get door property", target);
return;
}
if (door.objectReferenceValue == null) continue;
var serializedDoor = new SerializedObject(door.objectReferenceValue);
var lockState = serializedDoor.FindProperty("doorLockState");
serializedDoor.Update();
if (lockState == null)
{
EditorGUILayout.HelpBox("There was an error in the editor script!\nPlease check the log", MessageType.Error);
Debug.LogError("Couldn't get lockState property", target);
return;
}
// HERE OVERWRITE
if (shouldOverwrite)
{
lockState.boolValue = _globalLockState.boolValue;
}
else
{
EditorGUILayout.PropertyField(lockState, new GUIContent("Door " + i + " Lockstate"));
}
serializedDoor.ApplyModifiedProperties();
}
serializedObject.ApplyModifiedProperties();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class SceneViewCameraMove : ScriptableObject
{
[MenuItem("Test/Move Scene View Camera")]
static public void MoveSceneViewCamera()
{
Vector3 position = SceneView.lastActiveSceneView.pivot;
position.z -= 10.0f;
SceneView.lastActiveSceneView.pivot = position;
SceneView.lastActiveSceneView.Repaint();
}
}