Unity3D Custom Inspector每帧重置变量

时间:2018-02-20 17:20:39

标签: c# unity3d

我对自定义检查员/编辑很陌生,这让我很烦恼。我在下面有自定义编辑器脚本来设置我的船舶对象(太空船,而不是海运船)。问题是,每次我将控制类型设置为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;
&#13;
&#13; 这是船级

&#13;
&#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;
&#13;
&#13;

1 个答案:

答案 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));