【问题标题】:Multiple dice throw mechanic C# Unity多掷骰子机制 C# Unity
【发布时间】:2020-10-15 20:06:04
【问题描述】:

我想计算多个骰子(你应该能够添加和减去骰子)并滚动它们。

现在我可以掷骰子并在控制台中获得读数。 我的问题:我不能让多个骰子工作......

这些是脚本:

骰子控制器:

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

public class DiceController : MonoBehaviour
{
    public Dice dice;
    public GameObject dicePre;

    public int count = 1;


void Update()
{   
    GameObject[] dices = GameObject.FindGameObjectsWithTag("Dice");
    if(count - 1 == dices.Length){
        for (int i = 0; i < count; i++)
            {
                Instantiate(dicePre, new Vector3(i * 1.1F, 0, 0), Quaternion.identity);
            }
    }
    else if(count -1 < dices.Length){
        return;
    }
}

    public void Throw()
    {
        GameObject[] dices = GameObject.FindGameObjectsWithTag("Dice");
        foreach(GameObject dic in dices){
            dice = dic.GetComponent<Dice>();
            dice.RollDice();
        }
        
    }

    public void Plus(){        //add dice
        count++;
    }

    public void Minus(){       //substract dice
        count--;
    }
}

骰子面:

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

public class DiceSide : MonoBehaviour
{
    bool onGround;
    public int sideValue;

    void OnTriggerStay(Collider col) {
        
        if(col.tag == "ground"){
            onGround = true;
        }
    }

    void OnTriggerExit(Collider col) {
        
        if(col.tag == "ground"){
            onGround = false;
        }
    }

    public bool OnGround(){
        return onGround;
    }

}

主骰子脚本:

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

public class Dice : MonoBehaviour
{
   Rigidbody rb;
   bool hasLanded;
   bool thrown;
   Vector3 initPos;

   public int diceValue;

   public DiceSide[] diceSides;
   
   private void Start(){
        rb = GetComponent<Rigidbody>();
        initPos = transform.position;
        rb.useGravity = false;    
   }


    private void Update(){
        if(Input.GetKeyDown(KeyCode.T)){
            RollDice();
        }

        if(rb.IsSleeping() && !hasLanded && thrown){
            hasLanded = true;
            rb.useGravity = false;
            rb.isKinematic = true;

            SideValueCheck();
        }
        else if(rb.IsSleeping() && hasLanded && diceValue == 0){
            RollAgain();
        }
    }

    public void RollDice(){

        if(!thrown && !hasLanded){
            thrown = true;
            rb.useGravity = true;
            rb.AddTorque(Random.Range(0,500), Random.Range(0,500), Random.Range(0,500));

        }
        else if(thrown && hasLanded){
            Reset();
        }
    }

    void Reset(){

        transform.position = initPos;
        thrown = false;
        hasLanded = false;
        rb.useGravity = false;
        rb.isKinematic = false;
    }

    void RollAgain(){
        Reset();
        thrown = true;
        rb.useGravity = true;
        rb.AddTorque(Random.Range(0,500), Random.Range(0,500), Random.Range(0,500));
    }

    void SideValueCheck(){
        diceValue = 0;
        foreach(DiceSide side in diceSides){
            
            if(side.OnGround()){
                diceValue = side.sideValue;
                Debug.Log("Eine " + diceValue + " wurde gewürfelt!");
            }
        }
    }

}

我怎样才能让它工作? 也在这里你可以下载我现在得到的所有东西的统一包: https://workupload.com/file/7brN4gTCeLu

【问题讨论】:

    标签: c# unity3d dice


    【解决方案1】:

    首先如前所述,我将直接制作类型的预制字段

    public Dice dicePre;
    

    那么我将一直使用FindGameObjectsWithTag 来获取当前实例。

    我宁愿在List 中跟踪它们,例如

    public class Dice : MonoBehaviour
    {
        // every instance will add itself to this list
        private static List<Dice> instances = new List<Dice>();
    
        // public read only access
        public static ReadOnlyCollection<Dice> Instances => instances.AsReadOnly();
    
        // Add yourself to the instances
        private void Awake()
        {
            instances.Add(this);
        }
    
        // Remove yourself from the instances
        private void OnDestroy()
        {
            instances.Remove(this);
        }
    }
    

    所以以后你可以简单地使用

    foreach(var dice in Dice.Instances)
    {
        dice.RollDice();
    }
    

    主要问题

    那么目前你正在检查

    if(count - 1 == dices.Length)
    

    如果是这样,你实例化count dices。

    • 如果你的骰子是空的并且你的数是3 怎么办? -> 什么都不会发生

    • 或者如果你已经有 2 个骰子,但数量是 3 -> 你生成 3 骰子并最终得到 5

    您需要实际检查骰子数量和count 之间的差异,然后仅添加或删除差异。

    为了解决这个问题,我不会在 Update 中这样做,而是使用类似的属性

    [SerializeField] private int _count;
    
    public int Count
    {
        get => _count;
        set
        {
            // Count can not be negative
            _count = Mathf.Max(0, value);
    
            // Now do something with this new value
    
            // check difference
            var dif = Dice.Instances.Count - _count;
    
            // if 0 -> nothing to do
            if(dif == 0)
            {
                return;
            }
    
            // if smaller then 0 -> need more dices
            if(dif < 0)
            {
                for(var i = dif; i < 0; i++)
                {
                    Instantiate(dicePre, Vector3.right * Dice.Instances.Count, Quaternion.identity);
                }
            }
            // dif bigger then 0 -> have to many dices
            else
            {
                for(var i = 0; i < dif; i++)
                {
                    DestroyImmediate(Dice.Instances[Dice.Instances.Count - 1]);
                }
            }
        }
    }
    
    [ContextMenu(nameof(Plus))]
    public void Plus()
    {      
        Count++;
    }
    
    [ContextMenu(nameof(Minus))]
    public void Minus()
    {  
        Count--;
    }
    

    【讨论】:

      【解决方案2】:

      我不知道团结...所以如果这不符合标准,那么我很乐意删除。

      public class DiceController : MonoBehaviour
      {
          public List<Dice> dices;
      
          void DiceController()
          {
              dices = new list<Dice>();
              dices.add(new Dice); //ensure always have at least 1 on start
          }
      
          public void Plus()
          {        
              dices.Add(new Dice);
          }
      
          //caller can decided, could be random which one get removed.
          //assume they all equal
          public void Minus(Dice dice){  
              dices.Remove(dice);
          }
      
          public void Throw()
          {
              foreach(Dice dice in dices){
                  dice.RollDice();
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-29
        • 1970-01-01
        • 1970-01-01
        • 2018-09-08
        • 2019-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多