无法改变字典对象上的精灵

时间:2014-10-21 14:59:53

标签: c# unity3d sprite

当我点击键盘上的某个键时,我正在尝试更改字典对象的精灵。但我不能这样做。这是我的代码

using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

public class plantingScript : MonoBehaviour {
    public float plantV = 0f;
    public float coordX = 0f;
    public float coordY = 0f;
    public float koordX = 0f;
    public float koordY = 0f;

    public walkingScript ws = new walkingScript();
    public loadGame loadLand ;
    public GameObject gameObj;
    //public SpriteRenderer spriteObj;
    public Dictionary<string,Tanah> tempTanah = new Dictionary<string, Tanah>();
    public Dictionary<string,GameObject> tempObjTanah = new Dictionary<string, GameObject>();


    void Awake(){
        //spriteObj = gameObj.AddComponent<SpriteRenderer>();
        loadLand = GameObject.Find ("loadGameObject").GetComponent<loadGame>();
        tempTanah = loadLand.myTanah;
        tempObjTanah = loadLand.objTanah;

    }

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        if(Input.GetKeyDown(KeyCode.V))
            cekLokasi();
    }

    void cekLokasi(){
        Debug.Log ("V pressed!");

        GameObject temp = null;

        coordX = (int)(gameObject.transform.localPosition.x / 0.8f + gameObject.transform.localPosition.y / 0.4f) / 2;
        coordY = (int)(gameObject.transform.localPosition.y / 0.4f - (gameObject.transform.localPosition.x / 0.8f)) / 2;

        if(ws.hadapAtas == true && ws.hadapKanan == true)
        {
            koordY = (int) coordY;
            koordX = (int) coordX + 1; 
        }
        else if(ws.hadapAtas == false && ws.hadapKanan == true)
        {
            koordY = (int) coordY;
            koordX = (int) coordX - 1; 
        }
        else if(ws.hadapAtas == false && ws.hadapKanan == false)
        {
            koordY = (int) coordY + 1;
            koordX = (int) coordX; 
        }
        else if(ws.hadapAtas == true && ws.hadapKanan == false)
        {
            koordY = (int) coordY + 1;
            koordX = (int) coordX; 
        }

        if(tempObjTanah.TryGetValue("land-"+koordY.ToString("0#")+"-"+koordX.ToString("0#"),out temp))
        {
            Sprite mySprite = null;
            Debug.Log ("Land found!");
            mySprite = loadLand.myTanah["land-"+koordY.ToString("0#")+"-"+koordX.ToString("0#")].spriteTanah["Garap"];
            Debug.Log ("Sprite found!");

            gameObj = tempObjTanah["land-"+koordY.ToString("0#")+"-"+koordX.ToString("0#")];
            gameObj.AddComponent<SpriteRenderer>();
            gameObj.GetComponent<SpriteRenderer>().sprite = mySprite;


            /*
            Sprite mySprite = null;
            Debug.Log ("Land found!");
            mySprite = loadLand.myTanah["land-"+koordY.ToString("0#")+"-"+koordX.ToString("0#")].spriteTanah["Garap"];
            Debug.Log ("Sprite found!");
            tempObjTanah["land-"+koordY.ToString("0#")+"-"+koordX.ToString("0#")].AddComponent<SpriteRenderer>();
            SpriteRenderer mySpriteRend = tempObjTanah["land-"+koordY.ToString("0#")+"-"+koordX.ToString("0#")].GetComponent<SpriteRenderer>();
            mySpriteRend.sprite = mySprite;
            }
            */
        }
    }
}

这就是gameObject的字典是如何制作的

using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;


public class loadGame : MonoBehaviour {
    public static loadGame loadSave;

    public GameObject objPrince;
    public Pangeran charPrince;
    public Transform prefPrince;

    public Sprite[] spriteTanah;
    public Dictionary<string, Tanah> myTanah = new Dictionary<string, Tanah>();
    public Dictionary<string, GameObject>objTanah = new Dictionary<string, GameObject>();
    public Tanah tempTanah;
    public GameObject tempObjTanah;
    public Transform prefTanah;
    public float mapX;
    public float mapY;
    public int i = 0;
    public int j = 0;
    public int rows = 9;
    public int column = 9;


    void Awake(){
        if(loadSave == null)
        {
            DontDestroyOnLoad(gameObject);
            loadSave = this;
        }
        else if(loadSave != this)
            Destroy(gameObject);

    }

    // Use this for initialization
    void Start () {
        Load ();

    }

    // Update is called once per frame
    void Update () {

    }

    public void Load(){
        if(File.Exists(Application.persistentDataPath + "/playerInfo.dat"))
        {

        }
        else
        {
            charPrince = new Pangeran ("Prince", "04Okt1993", 0, 0, 0, 0, 0, false, false);
            objPrince = GameObject.Instantiate (prefPrince, new Vector3 (0, 0, 0), Quaternion.identity) as GameObject;
            //objPrince.name = "Prince";
            charPrince.locationY = 0f;
            charPrince.locationX = 0f;
            charPrince.hadapAtas = false;
            charPrince.hadapKanan = true;
            charPrince.stamina = 100f;
            charPrince.exp = 0f;
            charPrince.speed = 0f;

            for(i = 0 ; i < rows ; i ++)
            {
                for(j = 0; j<column ; j++)
                {
                    mapX = (i-j) * 0.8f;
                    mapY = (i+j) * 0.4f;

                    if(i>=1 && j>=1 && i<=5 && j<=5)
                    {
                        prefTanah.name = "land-"+j.ToString("0#")+"-"+i.ToString("0#");
                        tempTanah = new Tanah("land-"+j.ToString("0#")+"-"+i.ToString("0#"),mapX,mapY,"land",spriteTanah[0],spriteTanah[1],spriteTanah[2]);
                        myTanah.Add("land-"+j.ToString("0#")+"-"+i.ToString("0#"),tempTanah);
                        tempObjTanah = GameObject.Instantiate(prefTanah, new Vector3(mapX,mapY,0),Quaternion.identity)as GameObject;
                        objTanah.Add("land-"+j.ToString("0#")+"-"+i.ToString("0#"),tempObjTanah);
                    }
                    else
                    {
                        prefTanah.name = "snow-"+j.ToString("0#")+"-"+i.ToString("0#");
                        tempTanah = new Tanah("snow-"+j.ToString("0#")+"-"+i.ToString("0#"),mapX,mapY,"snow");
                        myTanah.Add("snow-"+j.ToString("0#")+"-"+i.ToString("0#"),tempTanah);
                        tempObjTanah = GameObject.Instantiate(prefTanah, new Vector3(mapX,mapY,0),Quaternion.identity)as GameObject;
                        objTanah.Add("snow-"+j.ToString("0#")+"-"+i.ToString("0#"),tempObjTanah);
                    }
                }
            }

        }
    }
}

它出错了,说

  

NullReferenceException:未将对象引用设置为的实例   对象plantingScript.cekLokasi()(at   资产/脚本/ plantingScript.cs:78)

第78行

tempObjTanah["land-"+koordY.ToString("0#")+"-"+koordX.ToString("0#")].GetComponent<SpriteRenderer>().sprite = mySprite;

我试图用其他方式改变精灵,但我没有工作。 请帮我。谢谢。

1 个答案:

答案 0 :(得分:0)

如果Unity说它没有SpriteRenderer,那么它没有SpriteRenderer

gameObj.GetComponent<SpriteRenderer>()是空的,当您尝试从中访问sprite属性时,您会获得NullReferenceException

检查您是如何创建对象的,并确保它们附加了正确的组件。 SpriteRenderer不是默认组件。

编辑:在阅读了您的新代码示例后,我还有一些评论,但遗憾的是,这不是您问题的明确解决方案。

您的代码极难阅读和理解,主要是因为使用了描述不同内容的常见变量名称。

prefTanah.name = ...
tempTanah = ...
myTanah.Add(...);
tempObjTanah = ...
objTanah.Add(

prefTanah是预制件,但您将其名称更改为动态生成的内容。这个名字很有意义,但改变这样的名字不会。

然后你创建一个Tanah对象,我假设它是某种数据模型。然后将其添加到名为Tanah的{​​{1}}个对象的字典中。

但是你还要维护一个单独的myTanah字典,它似乎与GameObject个对象有关。

此外,Tanah在第二个代码示例中被分配了tempObjTanah,但在第一个代码示例中它被称为字典。即使这些在不同的范围内,对于外部观察者来说也很难理解。

不幸的是,我没有看到原始问题的直接解决方案,但我确信这是因为您的脚本非常混乱且难以理解。如果GameObject引用的预制确实有prefTanah,我唯一的猜测是你的词典不包含你认为它包含的内容。我的建议是仔细检查你的脚本并确保它正在做你认为正在做的事情。您还可以尝试将整个脚本发布到pastebin或其他内容,以便我们可以获得有关正在发生的事情的更多背景信息。