如何根据字典条目换出 Unity2D 中的精灵?

How to swap out a sprite in Unity2D based on a Dictionary entry?

我完全不熟悉 Unity 和 C# 编程,如果这有点初级,我深表歉意;

基本上我想在我的游戏中改变一个精灵10秒,然后再变回原来的精灵。我已将此 sprite 存储在字典条目中,以及我希望在列表中更改为的 sprite。我用一个循环创建这些字典条目,该循环根据我们在循环中的位置过滤精灵的正确名称和其他条目值。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;

public class PaddleAbilities : MonoBehaviour
{

    public Dictionary<string, Ability> AbilitiesDictionary = new Dictionary<string, Ability>();

    [Header("GUI Sprites")]
    public List<Sprite> abilitySprites;

    [Header("Ability Costs")]
    public int Q_Cost;
    public int W_Cost;
    public int E_Cost;
    public int R_Cost;

    [Header("Ability Cooldowns")]
    public float Q_Cooldown;
    public float W_Cooldown;
    public float E_Cooldown;
    public float R_Cooldown;

    //ability ready timers
    public bool Q_Ready = true;
    public bool W_Ready = true;
    public bool E_Ready = true;
    public bool R_Ready = true;

    //access Scripts
    [Header("Other")]
    public GameManager gameManager;
    public Paddle paddle;
    public int Score;
    public string thisPlayer;
    private Vector2 Position;

    void Awake()
    {
        //get our Game Objects
        gameManager = GameObject.Find("GameManager").GetComponent<GameManager>();
        paddle = this.gameObject.GetComponent<Paddle>();

        //Get resource position
        Position = this.gameObject.transform.position;
    }

    void Start()
    {
        //which player is this script assigned to?
        if (Position.x < 0)
        {
            thisPlayer = "P1";
            Score = gameManager.scoreValueP1;
        }
        else if (Position.x > 0)
        {
            thisPlayer = "P2";
            Score = gameManager.scoreValueP2;
        }

        for (int i = 1; i < 5; i++)
        {
            int Cost = 0;
            switch (i)
            {   case 1: 
                    Cost = Q_Cost; 
                    break;
                case 2: 
                    Cost = W_Cost; 
                    break;
                case 3: 
                    Cost = E_Cost; 
                    break;
                case 4: 
                    Cost = R_Cost; 
                    break; 
            }

            float Cooldown = 0;
            switch (i)
            {   case 1: 
                    Cooldown = Q_Cooldown; 
                    break;
                case 2: 
                    Cooldown = W_Cooldown; 
                    break;
                case 3: 
                    Cooldown = E_Cooldown; 
                    break;
                case 4: 
                    Cooldown = R_Cooldown; 
                    break; 
            }

            if(thisPlayer == "P1")
            {
                string P1Name = "Ability" + i + "_P1";
                AbilitiesDictionary.Add(P1Name, new Ability(P1Name, GameObject.Find(P1Name).GetComponent<SpriteRenderer>().sprite, Cost, Cooldown));
            }
            else if (thisPlayer == "P2")
            {
                string P2Name = "Ability" + i + "_P2";
                AbilitiesDictionary.Add(P2Name, new Ability(P2Name, GameObject.Find(P2Name).GetComponent<SpriteRenderer>().sprite, Cost, Cooldown));
            }
        }
    }

    public class Ability
    {
        public string SpriteName { get; set; }
        public Sprite AbilitySprite { get; set; }
        public int AbilityCost { get; set; }
        public float AbilityCooldown { get; set; }

        public Ability(string spriteName, Sprite abilitySprite, int abilityCost, float abilityCooldown)
        {
            this.SpriteName = spriteName;
            this.AbilitySprite = abilitySprite;
            this.AbilityCost = abilityCost;
            this.AbilityCooldown = abilityCooldown;
        }
    }

    void Update()
    {
        AbilitiesRead();

        if (thisPlayer == "P1")
        {
            Score = gameManager.scoreValueP1;
        }
        else if (thisPlayer == "P2")
        {
            Score = gameManager.scoreValueP2;
        }
    }

    //Key press check gets called in update
    public void AbilitiesRead()
    {
        if (Input.GetKeyDown(KeyCode.Q) && Q_Ready && Score >= AbilitiesDictionary["Ability1_" + thisPlayer].AbilityCost)
        {
            Debug.Log(thisPlayer + " attempted to spawn a ball.");
            StartCoroutine(ServeBall());
        }
    }

    //ENUMERATORS v
    private IEnumerator SkillDuration(float WaitTime)
    {
        //Debug.Log("Skill is active. Waiting for skill to deactivate.");
        yield return new WaitForSeconds(WaitTime);
    }

    private IEnumerator ServeBall()
    {
        gameManager.serveTowards = paddle.Opponent; //make sure we serve at our opponent when this ability is called
        gameManager.SpawnBall(1); //spawn a Ball (the ball will use this paddle.Opponent to determine which direction to go in.)

        Q_Ready = false; //this ability is now on cooldown.

        Score -= AbilitiesDictionary["Ability1_" + thisPlayer].AbilityCost; //deduct our Ability Cost
        AbilitiesDictionary["Ability1_" + thisPlayer].AbilitySprite = abilitySprites[1]; //swap out Q_sprite for this player to the greyscale version "Q_Ability_onCooldown.psd"
        yield return StartCoroutine(SkillDuration(AbilitiesDictionary["Ability1_" + thisPlayer].AbilityCooldown)); //WaitForSeconds for the amount of time we want to cooldown for.
        AbilitiesDictionary["Ability1_" + thisPlayer].AbilitySprite = abilitySprites[0]; //swap out Q_sprite for this player to the color version "Q_Ability.psd"

        Q_Ready = true; //this ability is now ready to be used again.
    }
}

这是层次结构中的精灵。我能够确认我的字典条目确实找到了 sprite,但是当我将该条目设置为等于列表中我想要更改为的 sprite 时,Unity 方面没有任何反应。

Ability Sprites in Hierarchy

 AbilitiesDictionary.Add(P1Name, new Ability(P1Name, GameObject.Find(P1Name).GetComponent<SpriteRenderer>().sprite, Cost, Cooldown));

与其引用精灵本身,不如引用 SpriteRenderer 并像这样交换 SpriteRenderer 的精灵:

在你的技能中Class引用渲染器:

 public class Ability
{
    public string SpriteName { get; set; }
    public SpriteRenderer AbilitySprite { get; set; }
    public int AbilityCost { get; set; }
    public float AbilityCooldown { get; set; }

    public Ability(string spriteName, Sprite abilitySprite, int abilityCost, float abilityCooldown)
    {
        this.SpriteName = spriteName;
        this.AbilitySprite = abilitySprite;
        this.AbilityCost = abilityCost;
        this.AbilityCooldown = abilityCooldown;
    }
}

将渲染器添加到您的 Class

if(thisPlayer == "P1")
        {
            string P1Name = "Ability" + i + "_P1";
            AbilitiesDictionary.Add(P1Name, new Ability(P1Name, GameObject.Find(P1Name).GetComponent<SpriteRenderer>(), Cost, Cooldown));
        }

交换精灵:

AbilitiesDictionary["Ability1_" + thisPlayer].AbilitySprite.sprite = abilitySprites[1];

代码未经测试,因此不保证没有拼写错误 ;)