在字符串和unums中切换性别代词

时间:2017-10-24 18:49:22

标签: c# unity3d replace enums

我正在制作一个涉及玩家选择性别的游戏,并希望用正确的代词反映玩家选择的对话。我正在考虑使用布尔值,但建议不要因为它似乎有点不好使其中一个性别是真的而另一个是假的。所以尝试在这上面使用枚举,但我唯一的问题是如何正确实现它并让它工作。之前没有真正使用过很多用于字符串的枚举。

这是我到目前为止所做的:

public class UITextBoxScript : MonoBehaviour
{

    public Text mytext;
    enum Gender
    {
        None, Male, Female
    }
    enum States
    {
        Instructions, Warning, YourGender, Test
    }

    Gender playerGender = Gender.None;

    Gender playersGender = Gender.Male;

    Gender playGender = Gender.Female;


    int gender = 0; // using 0 or 1  (or 0, 1, 2.. if you might ever have 'unset')
    string[] heshe = { "he", "she" };
    string[] hisher = { "his", "her" };
    string[] himher = { "him", "her" };

然后,这是它应该击中并影响用户选择的目标区域:

    void state_YourGender()
    {
        mytext.text = "Okay!" +
            "\n" +
            "\n" +
            "What is your love interest gender?" +
            "\n" +
            "\n" +
            "\n" +
            "\n" +
            "A) Male" +
            "\n" +
            "\n" +
            "S) Female";

        timer -= Time.deltaTime;

        if (Input.GetKeyDown(KeyCode.A))
        {
            myState = States.Test;
            gender = 0;
            Gender playersGender = Gender.Male;
        }

        else if (Input.GetKeyDown(KeyCode.S))
        {
            myState = States.Test;

        }
    }

    void state_Test()
    {
        string phrase=" _heshe_was really happy";
        string newPhrase = phrase.Replace("_HESHE_", heshe[gender]);

        timer -= Time.deltaTime;

        if (timer <= 0 && Input.GetKeyDown(KeyCode.Space))
        {
            timer = timerVal;
            myState = States.YourGender;
        }
    }

我一直试图尝试并找到一种方法来调用字符串返回给我,但字符串本身根本没有返回。我也正在使用mytextbox和一个小盒子的区域来显示对话,它一直很好用;那里没有问题。有什么建议或提示吗?

1 个答案:

答案 0 :(得分:1)

使用枚举来存储像性别这样的独占值是个好主意,但是代码中有一些设计决策并不是好主意。首先,您已经有四个全局变量来存储一个玩家的性别角色。这已经太多了,而且你添加的每个玩家或NPC都会变得更糟。相反,创建一个用于存储人员的类:

public class Person
{
    public string Name { get; private set; }
    public Gender Gender { get; private set; }
    public Gender LoveInterestGender { get; private set; }
    public Person(string name, Gender gender, Gender loveInterestGender)
    {
        if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullException(nameof(name));

        Name = name;
        Gender = gender;
        LoveInterestGender = loveInterestGender;
    }
}

初学者奇怪地不愿意创建新课程。不要;这是简化代码的主要方式。现在,您可以通过代码或UI创建播放器:

var player = new Person(name: "Hiro Protagonist", gender: Gender.Male, loveInterestGender: Gender.Female);

尝试使用字符串替换自定义对话框也是一个坏主意;通常你想改变实际的对话,而不是用“她”等替换每个“他”。您需要为要遵循的对话框指定规则。例如,我们可以根据发言者和听众的性别为每个对话框指定不同的规则。你是怎样做的?当然还有另一堂课。虽然,由于我不会进入的原因,在这种特殊情况下,readonly结构会更好:

public struct DialogSpecifier : IEquatable<DialogSpecifier>
{
    public readonly Gender SpeakerGender;
    public readonly Gender ListenerGender;

    public DialogSpecifier(Gender speakerGender, Gender listenerGender)
    {
        SpeakerGender = speakerGender;
        ListenerGender = listenerGender;
    }

    public bool Equals(DialogSpecifier other)
    {
        return SpeakerGender==other.SpeakerGender
            && ListenerGender==other.ListenerGender;
    }
}

好的,现在我们有人和对话规则。我们如何使用这些规则让人们互相交谈?我们可以针对每个性别的每个规则为每个人编写一堆代码。哇,这是很多代码!我们如何再次简化代码?哦,是的,创建一个类:

public class Dialogue
{
    Dictionary<DialogSpecifier, string> specifiedDialog = new Dictionary<DialogSpecifier, string>();

    public Dialogue(string noneToNone)
    {
        specifiedDialog.Add(new DialogSpecifier(Gender.None, Gender.None), noneToNone);
    }

    public Dialogue Add(DialogSpecifier specifier, string dialogue)
    {
        specifiedDialog.Add(specifier, dialogue);
        return this;
    }

    public string OpeningGambit(Person speaker, Person listener)
    {
        string gambit;
        if (specifiedDialog.TryGetValue(new DialogSpecifier(speakerGender: speaker.Gender, listenerGender: listener.Gender),
                out gambit))
            return gambit;

        return specifiedDialog[new DialogSpecifier(Gender.None, Gender.None)];
    }
}

好的,现在让我们创建一些人和对话:

var introduction = new Dialogue("Hello")
    .Add(new DialogSpecifier(Gender.Male, Gender.Male), "Wassup?");
var npc = new Person(name: "Juanita Marquez", gender: Gender.Female, loveInterestGender: Gender.Male);

var gambit = introduction.OpeningGambit(player, npc);

简单,对吧?那是因为我们创建了类,并没有尝试为每个可能的排列编写代码。这也很容易扩展;我们可以针对不同的情况添加开局,或者将specifiedDialog更改为Dictionary<DialogSpecifier, List<string>>,这样我们就可以为每个说明符设置一个开头列表而不是一个开头。我们可以向DialogSpecifier添加更多规则,例如,如果收听者是发言人的LoveInterestGender,则表现不同。这样做只需要改变一个班级;每次添加内容时都不必重写所有代码。