【问题标题】:Can I get random damage roll from a function in constructor of a class?我可以从类的构造函数中的函数获得随机伤害掷骰吗?
【发布时间】:2016-08-05 17:34:33
【问题描述】:

我有一个关于在构造函数中使用函数的问题。 我正在创建一个简单的库存,它由 2 个脚本组成:EquipmentGenerator.cs 和 CharacterInventory.cs。 后者还可以访问掷骰子脚本。

简而言之,就是这一行:

Add_to_inventory(new Weapon("Longsword", "Most popular type of sword, weapon of choice for many warriors and mercenaries.", false, 15, "gp", 3, "Longsword", "1d8", "slashing", diceRolls.Rolld8(), new List <string>() {"Versatile (1d10)"}));

我需要能够使用 diceRolls.Rolld8(),它在 Weapon 类构造函数中作为 c_dmg_roll 以便每次我得到新结果(它只是 Random.Range)。

EquipmentGenerator 由以这种方式创建的类组成:

[System.Serializable]
public class Item : IComparable<Item>
{
    public string name, description;
    public bool stackable;
    public int value;
    public string coin_type;
    public int weight;
    //  public string model_path;

    public Item (string c_name, string c_description, bool c_stackable, int c_value, string c_coin_type, int c_weight)
    {
        name = c_name;
        description = c_description;
        stackable = c_stackable;
        value = c_value;
        coin_type = c_coin_type;
        weight = c_weight;
        //  model_path = c_model_path;
        //, string c_model_path)
    }
    public int CompareTo(Item other)
    {
        return String.Compare (name, other.name);
    }
}

[System.Serializable]
public class Weapon : Item, IComparable <Weapon>
{
    public string weapon_prof;
    public string dmg_die;
    public string dmg_type;
    public int dmg_roll;
    public List <string> weapon_properties;

    public Weapon (string c_name, string c_description, bool c_stackable, int c_value, string c_coin_type, int c_weight, string c_weapon_prof, string c_dmg_die, string c_dmg_type, int c_dmg_roll, List <string> c_weapon_properties) : base (c_name, c_description, c_stackable, c_value, c_coin_type, c_weight)
    {
        weapon_prof = c_weapon_prof;
        dmg_die = c_dmg_die;
        dmg_type = c_dmg_type;
        dmg_roll = c_dmg_roll;
        weapon_properties = c_weapon_properties;            
    }
    public int CompareTo(Weapon other)
    { return String.Compare (name, other.name);     }
}

这是 CharacterInventory:

public class CharacterInventory : MonoBehaviour
{
    public List<Weapon> char_inv_weapon;
    public List<Armor> char_inv_armor;
    public List<Potion> char_inv_potion;
    public List<Item> char_inv_other;

    DiceRolls diceRolls = new DiceRolls();

    void Start () {
        Add_to_inventory(new Weapon("Longsword", "Most popular type of sword, weapon of choice for many warriors and mercenaries.", false, 15, "gp", 3, "Longsword", "1d8", "slashing", diceRolls.Rolld8(), new List <string>() {"Versatile (1d10)"}));
        Add_to_inventory(new Weapon("Shortsword", "Sharp, lightweight, piercing weapon commonly used by shorter races and rogues.", false, 10, "gp", 2, "Shortsword", "1d6", "piercing", diceRolls.Rolld6(), new List <string>() {"Light", "Finesse"}));
        Add_to_inventory(new Weapon("Quarterstaff", "Long, blunt staff, typically made of wood. Common for wanderers, travellers, seen in use by wizards, druids and monks.", false, 2, "sp", 4, "Quarterstaff", "1d6", "blunt", diceRolls.Rolld6(), new List <string>() {"Versatile (1d8)"}));


        // Debug: Count current inventory items and list them in Console via foreach loop

        Debug.Log ("Current number of weapons in character's inventory: " + char_inv_weapon.Count + ". Check all item details in Unity Editor's Inspector on the right. Below see a list of weapons:");
        foreach (Weapon weapon in char_inv_weapon) {
            Debug.Log ("Weapon name and description plus rolled damage:  " + weapon.name + ":  " + weapon.description + " Rolled damage: " + weapon.dmg_roll);
        }

        Debug.Log ("Current number of weapons in character's inventory: " + char_inv_weapon.Count + ". Check all item details in Unity Editor's Inspector on the right. Below see a second roll of list of weapons:");
        foreach (Weapon weapon in char_inv_weapon) {
            Debug.Log ("Weapon  and description plus damage rolled second time:  " + weapon.name + ":  " + weapon.description + " Rolled damage: " + weapon.dmg_roll);
        }

    }

    // Sorting

    public void Add_to_inventory(Item it)
    {
        if (it is Weapon)
        {
            char_inv_weapon.Add((Weapon)it);
            char_inv_weapon.Sort();
        }
        else if (it is Armor)
        {
            char_inv_armor.Add((Armor)it);
            char_inv_armor.Sort();
        }
        else if (it is Potion)
        {
            char_inv_potion.Add((Potion)it);
            char_inv_potion.Sort();
        }
        else
        {
            char_inv_other.Add(it);
            char_inv_other.Sort();
        }
    }

掷骰子的部分脚本/类 DiceRolls:

    // define d8 rolls
   public int Rolld8() {
        d8 = Random.Range (1, 9);
        return d8;
    }

除了一件事之外,一切都很好:我每次访问 Weapon.dmg_roll 时都不会受到随机伤害。 Debug.Log 每次都显示相同的数字。 我只是在学习,但找不到如何使其工作的信息。 您有什么想法可以解决吗?

我可以创建一个“if”来检查字符串是否为 dmg_die == "1d8",然后从函数中进行滚动。但是有没有办法在没有这一步的情况下使随机滚动发生?在添加到列表的武器参数中将 dmg_roll 写为 Random.Range 也不会滚动另一个数字,即使我将其放入 Update() 并由 Input.GetKeyDown 运行。

【问题讨论】:

    标签: c# class unity3d constructor unity5


    【解决方案1】:

    一切都很好,除了一件事:我不能每个人都受到随机伤害 是时候访问武器.dmg_roll了。

    将武器伤害抽象到它自己的类中,该类将被实例化一次。在您的方法调用中调用该类 IWeaponDamageService.Roll(IWeaponType type),该类通过调用您的其他对象来执行“命中”。老实说,我认为您正在寻找命令模式。

    http://www.dofactory.com/net/command-design-pattern

    在这里编辑:

    Debug.Log ("Current number of weapons in character's inventory: " + char_inv_weapon.Count + ". Check all item details in Unity Editor's Inspector on the right. Below see a list of weapons:");
    var weaponService = new WeaponService();
                foreach (Weapon weapon in char_inv_weapon) {
                    Debug.Log ("Weapon name and description plus rolled damage:  " + weapon.name + ":  " + weapon.description + " Rolled damage: " + weaponService.GetDamageRoll(weapon)
                }
    public class WeaponService{
    
    public int GetDamageRoll(object wpn){
    if(wpn.name == "LongSword"){
    return 49;
    }
    else{
    ...
    }
    }
    }
    

    编辑#3,用于 D&D!

    这是显示每种武器都有自己随机性的代码。我认为 DICEROLLS 被淘汰了。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var diceRolls = new DiceRolls();
                var inventory = new CharacterInventory();
    
                inventory.Add_to_inventory(new Weapon("Longsword",
                    "Most popular type of sword, weapon of choice for many warriors and mercenaries.", false, 15, "gp", 3,
                    "Longsword", "1d8", "slashing", diceRolls.Rolld8(), new List<string>() { "Versatile (1d10)" }));
                inventory.Add_to_inventory(new Weapon("Shortsword",
                    "Sharp, lightweight, piercing weapon commonly used by shorter races and rogues.", false, 10, "gp", 2,
                    "Shortsword", "1d6", "piercing", diceRolls.Rolld6(), new List<string>() { "Light", "Finesse" }));
                inventory.Add_to_inventory(new Weapon("Quarterstaff",
                    "Long, blunt staff, typically made of wood. Common for wanderers, travellers, seen in use by wizards, druids and monks.",
                    false, 2, "sp", 4, "Quarterstaff", "1d6", "blunt", diceRolls.Rolld6(),
                    new List<string>() { "Versatile (1d8)" }));
    
    
                // Debug: Count current inventory items and list them in Console via foreach loop
    
                Console.WriteLine("Current number of weapons in character's inventory: " + inventory.char_inv_weapon.Count +
                                  ". Check all item details in Unity Editor's Inspector on the right. Below see a list of weapons:");
                foreach (Weapon weapon in inventory.char_inv_weapon)
                {
                    Console.WriteLine("Weapon name and description plus rolled damage:  " + weapon.name + ":  " +
                                      weapon.description + " Rolled damage: " + weapon.dmg_roll);
                }
    
                Console.WriteLine("Current number of weapons in character's inventory: " + inventory.char_inv_weapon.Count +
                                  ". Check all item details in Unity Editor's Inspector on the right. Below see a second roll of list of weapons:");
                foreach (Weapon weapon in inventory.char_inv_weapon)
                {
                    Console.WriteLine("Weapon  and description plus damage rolled second time:  " + weapon.name + ":  " +
                                      weapon.description + " Rolled damage: " + weapon.dmg_roll);
                }
            }
        }
    
    
    
        [System.Serializable]
        public class Item : IComparable<Item>
        {
            public string name, description;
            public bool stackable;
            public int value;
            public string coin_type;
            public int weight;
            //  public string model_path;
    
            public Item(string c_name, string c_description, bool c_stackable, int c_value, string c_coin_type, int c_weight)
            {
                name = c_name;
                description = c_description;
                stackable = c_stackable;
                value = c_value;
                coin_type = c_coin_type;
                weight = c_weight;
                //  model_path = c_model_path;
                //, string c_model_path)
            }
    
            public int CompareTo(Item other)
            {
                return String.Compare(name, other.name);
            }
        }
    
        [System.Serializable]
        public class Weapon : Item, IComparable<Weapon>
        {
            public string weapon_prof;
            public string dmg_die;
            public string dmg_type;
            public int dmg_roll;
            public List<string> weapon_properties;
    
            public Weapon(string c_name, string c_description, bool c_stackable, int c_value, string c_coin_type,
                int c_weight, string c_weapon_prof, string c_dmg_die, string c_dmg_type, int c_dmg_roll,
                List<string> c_weapon_properties) : base(c_name, c_description, c_stackable, c_value, c_coin_type, c_weight)
            {
                weapon_prof = c_weapon_prof;
                dmg_die = c_dmg_die;
                dmg_type = c_dmg_type;
                dmg_roll = c_dmg_roll;
                weapon_properties = c_weapon_properties;
            }
    
            public int CompareTo(Weapon other)
            {
                return String.Compare(name, other.name);
            }
        }
    
    
        public class CharacterInventory
        {
            public List<Weapon> char_inv_weapon;
            public List<object> char_inv_armor;
            public List<object> char_inv_potion;
            public List<Item> char_inv_other;
    
    
            public CharacterInventory()
            {
                char_inv_weapon = new List<Weapon>();
                char_inv_armor = new List<object>();
                char_inv_potion = new List<object>();
                char_inv_other = new List<Item>();
            }
    
            // Sorting
    
            public void Add_to_inventory(Item it)
            {
                if (it is Weapon)
                {
                    char_inv_weapon.Add((Weapon) it);
                    char_inv_weapon.Sort();
                }
                //else if (it is Armor)
                //{
                //    char_inv_armor.Add((Armor) it);
                //    char_inv_armor.Sort();
                //}
                //else if (it is Potion)
                //{
                //    char_inv_potion.Add((Potion) it);
                //    char_inv_potion.Sort();
                //}
                else
                {
                    char_inv_other.Add(it);
                    char_inv_other.Sort();
                }
            }
        }
    
        internal class DiceRolls
        {
            public int Rolld8()
            {
                Random rnd1 = new Random();
                var d8 = rnd1.Next(1, 9);
                return d8;
            }
    
            public int Rolld6()
            {
                Random rnd1 = new Random();
                var d6 = rnd1.Next(1, 7);
                return d6;
            }
        }
    }
    

    【讨论】:

    • 谢谢,我相信你是对的。但我对 C# 编码真的很陌生,我不明白如何做我的代码。掷骰子是类 DiceRolls 中的方法。您能否举例说明我应该如何访问“Longsword”的 dmg_roll ( diceRolls.Rolld8() ) 以便它给我一个新的掷骰,而不仅仅是初始掷骰的结果?我真的很茫然,为这个项目做了大约 5000 行代码,但这对我来说是新的。我想我应该能够以某种方式通过 Debug.Log 在同一个脚本中访问它。因为谁知道呢,我以后可能需要。
    • 我无法在回复中发布代码,所以我修改了原来的
    • 非常感谢您的时间和精力,但我知道我可以以类似的方式进行操作 - 例如通过获取“1d8”字符串。所以我有带参数的武器(基于 Weapon 类构造函数),如果它的“dmg_die”有字符串“1d8”,我会运行 Random.Range(1,9)。如果是“1d6”,我会运行 Random.Range(1,7)。但我只是认为这将是低效的?可能比仅从武器自己的参数访问“diceRolls.Rolld8()”要慢。它已经在那里了,问题是,这个参数在访问时不会滚动一个新值。我不明白为什么这个值没有改变,它是一个函数。
    • 你在你的构造函数中传递你的值。克特只发生一次。您也许可以在 get,set 属性初始化之后尝试使用只读属性来访问您的 ctor 值。如果您将武器的 1d8 更改为 1d10,那么您就是在更改武器。每次更改武器的伤害时,都会影响该武器的输出。我看到的一个问题是,如果我的角色对 Maces 不好,他们的掷骰应该会受到影响。如果角色拥有剑术,+ 修饰符。
    • 好的,我想我明白了。因为它在构造函数中,所以它是只读变量,它的值是在运行时生成和存储的。那么无论如何我都无法更改该变量的值......所以也许我会使用那个“如果”,就像你提到的那样。你认为这会减缓滚动伤害的过程吗?我需要使用 if 或 case 检查列表中的项目是否有字符串(只有 5 个选项,所以 5 个 if)。然后根据这种情况运行一个函数(如您的示例中的名称)。如果我在游戏对象上实时使用它会降低性能吗?
    猜你喜欢
    • 2016-07-05
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    相关资源
    最近更新 更多