【问题标题】:Variable transferred from one script to another, unity变量从一个脚本转移到另一个,统一
【发布时间】:2021-05-26 22:43:12
【问题描述】:

我想编写一个井字游戏,但遇到了我的第一个问题:

我想从这个脚本中转移 int 变量“Level”:

using UnityEngine;

public class Box : MonoBehaviour
{
    public int index;
    public Mark mark;
    public bool isMarked;
    public static int Level;

    // [SerializeField] public int Level;

    private SpriteRenderer spriteRenderer;

    private void Awake()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();

        index = transform.GetSiblingIndex () ;
        mark = Mark.None;
        isMarked = false;
        Level = 0;
    }

    public void SetAsMarked (Sprite sprite, Mark mark, Color color)
    {
        this.mark = mark;
        Level = Level + 1;
        
        if (Level == 2)
        {
            isMarked = true;
            GetComponent<CircleCollider2D>().enabled = false;
        }

        spriteRenderer.sprite = sprite;
        spriteRenderer.color = color;
    }
}

进入这个脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Board : MonoBehaviour
{
    [Header("Input Settings : ")]
    [SerializeField] private LayerMask boxesLayerMask;
    [SerializeField] private float touchRadius;

    [Header("Mark Sprites : ")]
    [SerializeField] private Sprite spriteX;
    [SerializeField] private Sprite spriteO;

    [Header("Mark Colors Level 1: ")]
    [SerializeField] private Color colorX;
    [SerializeField] private Color colorO;

    [Header("Mark Colors Level 2: ")]
    [SerializeField] private Color colorX2;
    [SerializeField] private Color colorO2;

    public Mark[] marks;

    private Camera cam;

    private Mark currentMark;

    private void Start()
    {
        cam = Camera.main;

        currentMark = Mark.X;

        marks = new Mark[9];
    }

    private void Update()
    {   
        if (Input.GetMouseButtonUp(0))
        {   
             Vector2 touchPosition = cam.ScreenToWorldPoint(Input.mousePosition);

            Collider2D hit = Physics2D.OverlapCircle(touchPosition, touchRadius, boxesLayerMask);

            if (hit)//box ist touched
                HitBox(hit.GetComponent<Box>());
        }  
    }
   
    private void HitBox(Box box)
    {
        if(!box.isMarked)
            marks[box.index] = currentMark;

        box.SetAsMarked(GetSprite(), currentMark, GetColor());

        //chek if anybody wins:
        bool won = CheckIfWin();
        if (won)
        {
            Debug.Log(currentMark.ToString() + "Wins.");
        }

        SwitchPlayer();
    }    

    private bool CheckIfWin()
    {
        return
         AreBoxesMatched (0, 1, 2) || AreBoxesMatched (3, 4, 5) ||
         AreBoxesMatched (6, 7, 8) || AreBoxesMatched (0, 3, 6) ||
         AreBoxesMatched (1, 4, 7) || AreBoxesMatched (0, 1, 2) ||
         AreBoxesMatched (0, 4, 8) || AreBoxesMatched (2, 4, 6);
    }

    private bool AreBoxesMatched(int i, int j, int k)
    {
        Mark m = currentMark;
        bool matched = (marks[i] == m && marks[j] == m && marks[k] == m) ;

        return matched;
    }
    
    private void SwitchPlayer ()
    {
        currentMark = (currentMark == Mark.X) ? Mark.O : Mark.X ;
    }

    private Color GetColor()
    {
        if (Level == 1) // <- Here I want to get the variable from the other spript. 
        {
            return (currentMark == Mark.X) ? colorX : colorO;
        }
        else
            return (currentMark == Mark.X) ? colorX2 : colorO2;
    }

    private Sprite GetSprite () 
    {
        return (currentMark == Mark.X) ? spriteX : spriteO;
    }
}

,我确信这是可能的,并且已经在 Internet 上进行了搜索,但还没有进展我现在必须如何使用这个脚本来执行此操作。谢谢!

【问题讨论】:

    标签: c# unity3d variables tic-tac-toe


    【解决方案1】:

    您当前将 Box 类中的 Level 变量设置为静态,因此您应该能够引用 Box.Level 来访问您的 Level 变量。

    话虽如此,你构建它的方式对我来说似乎有点不对劲。看起来一块板会有九个盒子 - 所以你会实例化你的盒子对象九次并安排它们来制作你的板。如果我们遵循这一思路,则不清楚您的 Level 应该代表什么,但似乎 Level 不应该是静态的,或者应该属于不同的类。如果每个框之间的 Level 应该不同,那么您应该删除 static 修饰符,否则 Level 变量可能在您的 Board 类或其他更通用的类中更有意义。 SetAsMarked() 增加级别的事实让我感觉它不应该是静态的,您应该实例化多个框。然后 - 最后回到这如何回答您的问题 - 当您使用它自己存储的级别将其设置为标记时,该框可以获取并设置自己的颜色,这将更具结构意义。

    【讨论】:

      【解决方案2】:

      您可以使用GetComponent&lt;&gt;() 方法。 GetComponent 搜索附加到某个游戏对象的组件。在统一中,脚本可以是组件。

      这是从object1 游戏对象上的脚本中获取变量的示例。

      第一个脚本:

      public GameObject object1;
      
      void Update()
      {
          int number = object1.GetComponent<Script2>().num;
          Debug.Log(number);
      }
      

      附加到object1 游戏对象的名为“Script2”的第二个脚本:

      public int num = 5;
      

      第一个脚本将打印数字 5。这是因为 object1 上的 Script2 中的变量 num 设置为 5。

      重要提示:您需要公开访问的变量。


      将此应用于您的情况。

      现在,我们将把它应用到您的情况。我们应该像以前一样做同样的事情,但使用您的脚本。

      using UnityEngine;
      
      public class Box : MonoBehaviour
      {
          public int index;
          public Mark mark;
          public bool isMarked;
          public int Level;
      
          private SpriteRenderer spriteRenderer;
      
          private void Awake()
          {   
              spriteRenderer = GetComponent<SpriteRenderer>();
              index = transform.GetSiblingIndex () ;
              mark = Mark.None;
              isMarked = false;
              Level = 0;  
          }
          public void SetAsMarked (Sprite sprite, Mark mark, Color color)
          {
              this.mark = mark;
              Level = Level + 1;
              if (Level == 2)
              {
                  isMarked = true;
                  GetComponent<CircleCollider2D>().enabled = false;
              }
               spriteRenderer.sprite = sprite;
               spriteRenderer.color = color;
          }
      }
      

      那是你的脚本,做了一些改动,但这是我将使用的(因为其余的不是必需的)

          ...
          public int Level;
          ...
      

      首先,去掉这个变量中的静态。

      现在,我们应该像这样通过第二个脚本访问它:

          public GameObject object1;
          int level;
      
          void Update()
          {
               level = object1.GetComponent<name_of_script>().Level;
          }
      

      重要提示:将第一个脚本(您正在访问的脚本)的名称放在 中,其中显示name_of_script。我想我看到了你的班级名称,所以这就是你的情况(如果我没看错的话):

          public GameObject object1;
          int level;
      
          void Update()
          {
               level = object1.GetComponent<Box>().Level;
          }
      

      如果您在同一个对象上有两个脚本,只需像这样删除 object1 变量:

          int level;
      
          void Update()
          {
               level = GetComponent<name_of_script>().Level;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-21
        • 1970-01-01
        • 2020-06-09
        • 2014-01-25
        • 1970-01-01
        • 1970-01-01
        • 2017-11-07
        • 2011-02-08
        相关资源
        最近更新 更多