我对自定义检查员/编辑很陌生,这让我很烦恼。我在下面有自定义编辑器脚本来设置我的船舶对象(太空船,而不是海运船)。问题是,每次我将控制类型设置为AI时它只保留一帧,然后将其自身重置为播放器(默认值)。如上所述,自定义编辑器非常新,并且不知道出了什么问题。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(Ship))]
public class ShipInspector : Editor
{
enum Controlled
{
Player = 0,
AI = 1,
}
Ai shipAi;
Ship ship;
Controlled actualControll = Controlled.Player;
public override void OnInspectorGUI()
{
ship = (Ship)target;
shipAi = ship.gameObject.GetComponent<Ai>();
actualControll = ((Controlled)EditorGUILayout.EnumPopup("Controll Type", actualControll));
if (actualControll == Controlled.Player)
{
ship.isPlayer = true;
if (shipAi != null)
{
DestroyAi();
}
}
else if (actualControll == Controlled.AI)
{
ship.isPlayer = false;
if (shipAi == null)
{
CreateAi();
}
}
EditorGUILayout.Separator();
EditorGUILayout.LabelField("General Setup");
ship.maxHull = EditorGUILayout.IntField("Maximal Hull", ship.maxHull);
ship.maxShields = 0;
ship.maxEnergi = EditorGUILayout.IntField("Maximal battery", ship.maxEnergi);
ship.energiRegenRate = EditorGUILayout.FloatField("Energi regen cooldown", ship.energiRegenRate);
EditorGUILayout.Separator();
EditorGUILayout.LabelField("Weapon setup");
EditorGUILayout.LabelField("For positions : X, Y and Z are coordinates relative to");
EditorGUILayout.LabelField("ship's center, H is angle rotation around ship's center");
EditorGUILayout.PropertyField(serializedObject.FindProperty("primWeaponsPos"), true);
EditorGUILayout.PropertyField(serializedObject.FindProperty("secWaponsPos"), true);
serializedObject.ApplyModifiedProperties();
}
public void CreateAi()
{
shipAi = (Ai)ship.gameObject.AddComponent(typeof(Ai));
shipAi.ship = ship;
}
public void DestroyAi()
{
DestroyImmediate(shipAi, false);
shipAi = null;
}
}
&#13;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Ship : Targetable
{
public Vector3 camPos = new Vector3(0, -10, -30);
public Vector3 lightPos;
public ParticleSystem[] enginesParticles;
public ParticleSystem[] reverseEngineParticles;
public Vector4[] primWeaponsPos;
public Vector4[] secWaponsPos;
public List<PrimarWeaponController> primWeapons = new List<PrimarWeaponController>();
public List<SecundarWeaponController> secWeapons = new List<SecundarWeaponController>();
public EngineController engine;
AddonController addon;
public Animator anim;
public Rigidbody2D rb;
public Targetable target;
public float massModifier;
public float energiRegenRate;
public bool isPlayer;
public float breakDistance;
Ai ai;
/// <summary>
/// Weapons will be set as childs of this object.
/// </summary>
public Transform weaponBone;
void Start()
{
camPos = new Vector3(0, -10, -30);
InitializeEqipment(0, 0, 0, 0, -1);
rb = gameObject.GetComponent<Rigidbody2D>();
if (isPlayer == true)
{
Instantiate(Resources.Load("Light2", typeof(GameObject)) as GameObject, PublicFunctions.RotateAroundPoint2D(transform.position + lightPos, transform.position, transform.rotation.eulerAngles.z), Quaternion.Euler(-90, 0, transform.rotation.eulerAngles.z)).transform.SetParent(this.gameObject.transform, true);
}
hull = maxHull;
shields = 0;
energi = maxEnergi;
base.ColorTheDot();
Invoke("RegenEnergi", energiRegenRate);
if (isPlayer == false)
{
ai = GetComponent<Ai>();
ai.ship = gameObject.GetComponent<Ship>();
ai.InicializeAI();
}
}
void Update()
{
float t = ((rb.velocity.magnitude) / engine.maximalSpeed) / engine.speedGain * Time.deltaTime;
breakDistance = (rb.velocity.sqrMagnitude) * t + (((engine.speedGain * t) * (engine.speedGain * t)) / 2);
if (energi > maxEnergi) { energi = maxEnergi; } else if (energi < 0) { energi = 0; }
if (isPlayer == true)
{
Camera.main.transform.position = PublicFunctions.RotateAroundPoint2D(transform.position + camPos, transform.position, transform.rotation.eulerAngles.z - 180f);
Camera.main.transform.rotation = Quaternion.Euler(0, 0, transform.rotation.eulerAngles.z);
engine.Rotate(-Input.GetAxis("Mouse X"));
}
if (Input.GetKeyDown(DataManager.cof.targetFront) && isPlayer == true)
{
RaycastHit2D[] hits = Physics2D.RaycastAll(transform.position, transform.TransformDirection(Vector3.up));
foreach (RaycastHit2D hit in hits)
{
if (hit.collider.gameObject != this.gameObject)
{
Targetable tar = hit.collider.gameObject.GetComponent<Targetable>();
if (tar != null)
{
if (tar.faction != faction)
{
if (Vector3.Distance(transform.position, tar.gameObject.transform.position) <= 70f)
{
target = tar;
GameObject inst = Instantiate(Resources.Load("UI/RadarPointer", typeof(GameObject)) as GameObject, Vector3.zero, Quaternion.Euler(0f, 0f, 0f));
inst.transform.SetParent(GameObject.Find("Hud/Radar").transform);
RadarPointer rp = inst.GetComponent<RadarPointer>();
rp.actualType = RadarPointer.radarType.TargetedEnemy;
rp.target = target.gameObject;
break;
}
}
}
}
}
}
if (Input.GetKey(DataManager.cof.usePrimWeapon) && isPlayer == true)
{
foreach (PrimarWeaponController p in primWeapons)
{
p.Use();
}
}
if (Input.GetKey(DataManager.cof.useSecWeapon) && isPlayer == true)
{
foreach (SecundarWeaponController s in secWeapons)
{
s.Use();
}
}
if (Input.GetKeyDown(DataManager.cof.thrust) && isPlayer == true)
{
engine.ThrustUp();
}
if (Input.GetKeyUp(DataManager.cof.thrust) && isPlayer == true)
{
engine.ThrustDown();
}
if (Input.GetKeyDown(DataManager.cof.back) && isPlayer == true)
{
engine.ReverseUp();
}
if (Input.GetKeyUp(DataManager.cof.back) && isPlayer == true)
{
engine.ReverseDown();
}
if (Input.GetKey(DataManager.cof.useAddon) && isPlayer == true)
{
addon.Use();
}
if (isPlayer == false)
{
ai.Lock();
ai.Attack();
ai.Move();
}
}
void RegenEnergi()
{
energi = energi + 1;
Invoke("RegenEnergi", energiRegenRate);
}
void OnDrawGizmos()
{
Gizmos.color = Color.white;
Gizmos.DrawIcon(PublicFunctions.RotateAroundPoint2D(transform.position + lightPos, transform.position, transform.rotation.eulerAngles.z), "LightIcon");
Gizmos.DrawCube(PublicFunctions.RotateAroundPoint2D(camPos, transform.position, transform.rotation.eulerAngles.z - 180f), Vector3.one);
if (primWeaponsPos.Length > 0)
{
foreach (Vector4 v4 in primWeaponsPos)
{
Gizmos.DrawIcon(PublicFunctions.RotateAroundPoint2D(new Vector3(v4.x, v4.y, v4.z) + transform.position, transform.position, transform.rotation.eulerAngles.z + v4.w), "PrimWeaponIcon", true);
}
}
if (secWaponsPos.Length > 0)
{
foreach (Vector4 v4 in secWaponsPos)
{
Gizmos.DrawIcon(PublicFunctions.RotateAroundPoint2D(new Vector3(v4.x, v4.y, v4.z) + transform.position, transform.position, transform.rotation.eulerAngles.z + v4.w), "SecWeaponIcon", true);
}
}
Gizmos.color = Color.red;
Gizmos.DrawRay(transform.position, transform.TransformDirection(Vector3.up * breakDistance));
}
void InitializeEqipment(int gunId, int secId, int engId, int shldId, int addonId)
{
if (gunId != -1)
{
foreach (Vector4 pos in primWeaponsPos)
{
GameObject inst = Instantiate(Database.guns[gunId].gObject, PublicFunctions.RotateAroundPoint2D((Vector3)pos + transform.position, transform.position, transform.rotation.eulerAngles.z + pos.w), transform.rotation);
PrimarWeaponController prim = inst.GetComponent<PrimarWeaponController>();
prim.damage = Database.guns[gunId].damage;
prim.cooldown = Database.guns[gunId].cooldown;
prim.capacity = Database.guns[gunId].capacity;
prim.projectile = Database.guns[gunId].projectile;
prim.projectileSpeed = Database.guns[gunId].maximalSpeed;
prim.GunsCount = primWeaponsPos.Length;
prim.ship = GetComponent<Ship>();
inst.transform.SetParent(weaponBone);
primWeapons.Add(inst.GetComponent<PrimarWeaponController>());
if (isPlayer == true)
{
GameObject.Find("Hud/Top_Left/PrimSkill").GetComponent<SkillIcon>().noSkill = false;
GameObject.Find("Hud/Top_Left/PrimSkill").GetComponent<SkillIcon>().UpdateIcon();
GameObject.Find("Hud/Top_Left/PrimSkill").GetComponent<SkillIcon>().gunClass = Database.guns[gunId].thisType;
}
}
}
else
{
if (isPlayer == true)
{
GameObject.Find("Hud/Top_Left/PrimSkill").GetComponent<SkillIcon>().nullSkill();
}
}
if (secId != -1)
{
foreach (Vector4 pos in secWaponsPos)
{
GameObject inst = Instantiate(Database.rockets[secId].gObject, PublicFunctions.RotateAroundPoint2D((Vector3)pos + transform.position, transform.position, transform.rotation.eulerAngles.z + pos.w), transform.rotation);
SecundarWeaponController sec = inst.GetComponent<SecundarWeaponController>();
sec.damage = Database.rockets[secId].damage;
sec.cooldown = Database.rockets[secId].cooldown;
sec.speedGain = Database.rockets[secId].speedGain;
sec.maximalSpeed = Database.rockets[secId].maximalSpeed;
sec.count = Database.rockets[secId].capacity;
sec.turnRate = Database.rockets[secId].turnRate;
sec.type = Database.rockets[secId].thisRocket;
sec.projectile = Database.rockets[secId].projectile;
sec.ship = GetComponent<Ship>();
if (isPlayer == true)
{
GameObject.Find("Hud/Top_Left/SecSkill").GetComponent<SkillIcon>().noSkill = false;
GameObject.Find("Hud/Top_Left/SecSkill").GetComponent<SkillIcon>().UpdateIcon();
GameObject.Find("Hud/Top_Left/SecSkill").GetComponent<SkillIcon>().rocketType = Database.rockets[secId].thisRocket;
GameObject.Find("Hud/Top_Left/SecSkill").GetComponent<SkillIcon>().useAmmo = true;
GameObject.Find("Hud/Top_Left/SecSkill").GetComponent<SkillIcon>().count = Database.rockets[secId].capacity;
}
inst.transform.SetParent(weaponBone);
secWeapons.Add(inst.GetComponent<SecundarWeaponController>());
}
}
else
{
GameObject.Find("Hud/Top_Left/SecSkill").GetComponent<SkillIcon>().nullSkill();
}
EngineController eng = gameObject.AddComponent(typeof(EngineController)) as EngineController;
eng.speedGain = Database.engines[engId].speedGain;
eng.turnRate = Database.engines[engId].turnRate;
eng.maximalSpeed = Database.engines[engId].maximalSpeed;
engine = eng;
if (shldId != -1)
{
ShieldController shld = gameObject.AddComponent(typeof(ShieldController)) as ShieldController;
shld.capacity = Database.shields[shldId].capacity;
shld.regenRate = Database.shields[shldId].speedGain;
shld.ship = gameObject.GetComponent<Ship>();
}
if (addonId != -1)
{
AddonController add = gameObject.AddComponent(typeof(AddonController)) as AddonController;
add.cooldown = Database.addons[addonId].cooldown;
add.maximalAmmo = Database.addons[addonId].capacity;
if (isPlayer == true)
{
GameObject.Find("Hud/Top_Left/AddonSkill").GetComponent<SkillIcon>().noSkill = false;
GameObject.Find("Hud/Top_Left/AddonSkill").GetComponent<SkillIcon>().UpdateIcon();
GameObject.Find("Hud/Top_Left/AddonSkill").GetComponent<SkillIcon>().addonId = addonId;
}
addon = add;
}
else
{
if (isPlayer == true)
{
GameObject.Find("Hud/Top_Left/AddonSkill").GetComponent<SkillIcon>().nullSkill();
}
}
}
}
&#13;
答案 0 :(得分:1)
此属性:
Controlled actualControll
与其他字段不同,未从Ship
对象填充。给出一个这样的值:
Controlled actualControll = Controlled.Player;
// ...
actualControll = ((Controlled)EditorGUILayout.EnumPopup("Controll Type", actualControll));
您的检查器脚本无法确定该值是Controlled.Player
以外的任何值,即使从下拉列表中选择新值时,也会为该对象刷新检查器(每次都会发生这种情况)任何更改)该值首先设置为播放器,然后从下拉列表中查询(默认值=播放器),然后对该值进行操作(提示:它是Player
)。您的Ship
班级不知道是谁控制它。
嗯,它是通过ship.isPlayer
完成的,但该值是通过来自下拉列表中的值,但是下拉列表中的值不是同样由船舶驱动的本身已设置。您每帧都覆盖该值。
请改为尝试:
actualControll = ((Controlled)EditorGUILayout.EnumPopup(
"Controll Type", ship.isPlayer ? Controlled.Player : Controlled.AI));