Snippets
Created by
Alex Darby
last modified
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class ShaneEnumDemo : MonoBehaviour
{
// enums are a super awesome way to do the same thing you're doing because they're both a
// readable string *and* a number & in C# it's trivial to convert between them
public enum EMonster
{
Dragon, // unless you say otherwise this will == 0
Shoggoth, // and the rest will go up by 1 to the end of the enum
Yeti, // you can convert to string with .ToString() and to int with a cast
// ADD NEW VALUES ABOVE!
COUNT // this is the de facto standard way to know the number of values in an enum - it could be called anything
}
public enum EWeapon
{
Sword, // unless you say otherwise this will == 0
Axe, // and the rest will go up by 1 to the end of the enum
Dagger, // you can convert to string with .ToString() and to int with a cast
Bow,
// philosophically 'Nothing' represents the absence of a weapon
// this seems counter intuitive but will make sense further down
// for the code below to work you'd need to add all new values above this too
Nothing,
// ADD NEW VALUES ABOVE!
COUNT // this is the de facto standard way to know the number of values in an enum - it could be called anything
}
public bool m_bDoItTheOldWay = true;
[Tooltip( "0 == 0%; 1 == 100%")]
[Range( 0.01f, 0.99f)]
public float m_ChanceOfNoWeapon = 0.5f;
[Tooltip( "add weapons you want to drop, more of the same weapon increases its chance of dropping" )]
public EWeapon[] m_WeaponDropTable;
private List< EWeapon > m_lstWeaponDropTable;
void Start()
{
InitWeaponChanceLookupTable();
}
void Update()
{
EnumUtil.LogAllValuesToConsole<EMonster>();
EnumUtil.LogAllValuesToConsole<EWeapon>();
if( m_bDoItTheOldWay )
{
//
// to do the random thing the way you were you could do this
//
int iRandomWeapon = UnityEngine.Random.Range( 0, ((int)EWeapon.COUNT) * 2 );
// n.b. this relies on EWeapon.Nothing being AFTER all the other weapons in the enum
if( iRandomWeapon < ( (int)EWeapon.Nothing ) )
{
Debug.LogFormat( "You found a {0}!", ( (EWeapon)iRandomWeapon ).ToString() );
}
else
{
// no weapon
Debug.Log( "You didn't find anything!" );
}
}
else
{
//
// the way I'd do it uses the table built in InitWeaponChanceLookupTable() and it's naturally extensible
// you add more weapons to the enum and it'll just keep working
//
EWeapon eDroppedWeapon = m_lstWeaponDropTable[ UnityEngine.Random.Range( 0, m_lstWeaponDropTable.Count ) ];
switch( eDroppedWeapon )
{
case EWeapon.Nothing:
Debug.Log( "You didn't find anything!" );
break;
default:
Debug.LogFormat( "You found a {0}", eDroppedWeapon.ToString() );
break;
case EWeapon.COUNT:
Debug.LogError( "You should never hit this code unless there's a bug!" );
break;
}
}
}
void InitWeaponChanceLookupTable()
{
// or, here's another way, not necessarily qualitatively "better", but more extendible
// this is how you declare an array of enum values
//
// N.B. you can also use them as public members, arrays, or lists in Unity
// and the editor will handle them automatically...
//
// N.N.B. so, you could totally just put it as apublic member and set it in the editor,
// or put it on a scriptable asset (https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/scriptable-objects)
//
// N.N.B. this check means that this'll work without you setting up values in the editor
if( m_WeaponDropTable.Length == 0 )
{
m_WeaponDropTable = new EWeapon[]
{
// by varying the number of each in the array we change the likelihood of each one coming up
EWeapon.Axe,
EWeapon.Bow, EWeapon.Bow,
EWeapon.Dagger,
EWeapon.Sword, EWeapon.Sword, EWeapon.Sword,
};
}
// now build a lookup list to give the stats wanted for finding a weapon
// n.b. this constructor adds the array elenments into the list
m_lstWeaponDropTable = new List<EWeapon>( m_WeaponDropTable );
int iTotalIncludingNothings = Mathf.FloorToInt( ((float) m_lstWeaponDropTable.Count ) * ( 1f / m_ChanceOfNoWeapon ) );
int iNothingsToAdd = ( iTotalIncludingNothings - m_lstWeaponDropTable.Count );
// N.B. you might want to add 1 to iNothingsToAdd
// or if you set m_ChanceOfNoWeapon too low you'll never actually get "no weapon" added
for( int i = 0; i < iNothingsToAdd; ++i )
{
m_lstWeaponDropTable.Add( EWeapon.Nothing );
}
}
}
/////////////////////////////////////////////////////////////////////////////
public static class EnumUtil
{
public static IEnumerable<TEnum> GetAllValues<TEnum>()
where TEnum : struct, IConvertible, IComparable, IFormattable
{
return Enum.GetValues( typeof( TEnum ) ).Cast<TEnum>();
}
public static void LogAllValuesToConsole<TEnum>()
where TEnum : struct, IConvertible, IComparable, IFormattable
{
var aeAllValues = EnumUtil.GetAllValues<TEnum>();
foreach( TEnum eValue in aeAllValues )
{
System.Console.WriteLine( string.Format( "--> {0} [as int:{1}]", eValue.ToString(), eValue.ToUInt32( null ) ) );
}
}
}
|
Comments (0)
You can clone a snippet to your computer for local editing. Learn more.