简体   繁体   中英

Unity3D Custom Inspector resets variable every frame

I'm very new to custom inspector/editor and this troubles me a lot. I have custom editor script below to set my ship object(a space ship, not a sea one).Problem is, every time i set control type to AI it stays only one frame and and then reset itself to Player(default value).As said, very new to custom editor and have no idea what is wrong.

 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; } } 
This is ship class

 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(); } } } } 

Inspector script fields are not serialized.

This property:

Controlled actualControll

Is not filled from your Ship object, unlike your other fields. This one is given a value like this:

Controlled actualControll = Controlled.Player;
// ...
actualControll = ((Controlled)EditorGUILayout.EnumPopup("Controll Type", actualControll));

Your inspector script has no way of determining that the value is every anything other than Controlled.Player , as even when you select a new value from the dropdown, when the inspector is refreshed for that object (which happens every time anything changes) the value is first set to Player, then queried from a dropdown (default value = Player) and then acted upon that value (hint: it's Player ). Your Ship class has no idea who controls it.

Well, it does via ship.isPlayer , but that value is driven by the value from the dropdown, but the value in the dropdown is not likewise driven by what the ship itself has set. You override the value every frame.

Try this instead:

actualControll = ((Controlled)EditorGUILayout.EnumPopup(
    "Controll Type", ship.isPlayer ? Controlled.Player : Controlled.AI));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM