[英]Multiple dice throw mechanic C# Unity
I would like to istantiate multiple dices (you should be able to add and substract dices) and roll them.我想创建多个骰子(你应该能够添加和减去骰子)并滚动它们。
For now I can roll a dice and get the readout in the console.现在我可以掷骰子并在控制台中获得读数。 My problem: I can't get multiple dice to work...我的问题:我不能让多个骰子工作......
These are the scripts:这些是脚本:
the dice controller:骰子 controller:
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--;
}
}
the dice sides:骰子面:
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;
}
}
the main dice script:主骰子脚本:
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!");
}
}
}
}
How can I get this to work?我怎样才能让它工作? also here you can download the unitypackage with everything i got right now: https://workupload.com/file/7brN4gTCeLu也在这里你可以下载我现在得到的所有东西的统一包: https://workupload.com/file/7brN4gTCeLu
First as said I would directly make the prefab field of type首先如前所述,我将直接制作类型的预制字段
public Dice dicePre;
then I would not use FindGameObjectsWithTag
all the time to get current instances.那么我不会一直使用FindGameObjectsWithTag
来获取当前实例。
I would rather keep track of them in a List
like eg我宁愿在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);
}
}
So later you can simply use所以以后你可以简单地使用
foreach(var dice in Dice.Instances)
{
dice.RollDice();
}
Then currently you are checking那么目前你正在检查
if(count - 1 == dices.Length)
and if so you instantiate count
dices.如果是这样,你实例化count
骰子。
So what if your dices is empty and your count is 3
?那么如果你的骰子是空的并且你的计数是3
怎么办? -> nothing would happen -> 什么都不会发生
Or what if you already have 2 dices but count is 3
-> you spawn 3
dices and end up with 5
!或者,如果您已经有 2 个骰子但计数为3
-> 您生成3
骰子并最终得到5
怎么办!
You would need to actually check the difference between the dices amount and count
and either add or remove only the difference.您需要实际检查骰子数量和count
之间的差异,然后仅添加或删除差异。
In order to fix this I would not do this in Update
but rather using a property like为了解决这个问题,我不会在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--;
}
i do not know unity... so if this is off base with regards to that then i will gladly delete.我不知道团结...所以如果这与此无关,那么我很乐意删除。
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();
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.