- Home /
Plug and Play UnityEvents/Methods?
So I've been working on a game that uses a lot of very similar classes and I'm going to have some non-programmers working on the project. To this end I have created a nice little GUI that allows them to add NPCs, Jobs, Locations etc. that will then be used later in the game logic.
Here is how it currently looks to add a Job for instance:
So this is what the other designers will use to add in a job. This works great for this object:
JobList.cs
public class JobList : ScriptableObject { public List<Job> jobList; }
Job.cs
[System.Serializable]
public class Job {
public string title;
public string description;
public int wage;
public int gapBetweenPayments;
public int creativityRequired;
public int tempermentRequired;
public int fitnessRequired;
public int attractivenessRequired;
public int sociabilityRequired;
public int intellectRequired;
public List<string> contactsRequired;
}
However the next step is to create an object like this: Trait.cs:
[System.Serializable]
public class Trait {
public string title;
public string description;
public List<Effect> effects;
public void Apply()
{
foreach(Effect e in effects)
{
e.Apply(Character.character);
}
}
}
Effect.cs:
public class Effect : UnityEvent {
public UnityEvent apply;
public string title;
public void Apply(Character character)
{
}
}
The idea would then be that I write a bunch of generic functions such as dealing damage, giving them money etc. The designers input the numbers they wish to use. That version of the function then gets added to "currentTrait.effects" and when the player has that trait they will do something like:
foreach(Trait t in charactersListOfTraits)
{
t.Apply();
}
This is the closest I've gotten:
[System.Serializable]
public class ChangeMoney : Effect {
public int amount;
public void Apply (Character character)
{
Action(character);
}
private void Action (Character character)
{
character.currentMoney += amount;
Debug.Log(title + " was called and added this: " + amount);
}
}
Using an int slider to determine what amount will be and then adding a version of CurrentMoney.cs by:
OnGUI(){
if(GUILayout.Button("Add Change Money"))
{
ChangeMoney newEffect = new ChangeMoney();
newEffect.amount = amount;
newEffect.title = "Change Money";
currentTrait.effects.Add(newEffect);
}
}
This results in this:
Which is great and shows its Serializable - It will even know its a ChangeMoney and not just an effect when I Debug.Log(trait.title) - but hasn't added the functionality (Including when tested in game) that I wanted. I've been working on this problem alone for a few days now and feel like I must be stumbling over something really basic or my codes just plain wrong. Any pointers in the right direction would be great.
Answer by mythirdalias · Jan 15, 2018 at 01:17 AM
So after a lot of farting around it turns out I've almost had it several times and my lack of understanding about delegates was to blame. For anyone who is interested in this sort of thing this was my solution:
Effect.cs (Base class)
[System.Serializable]
public abstract class Effect : ScriptableObject {
public abstract void Apply(Character character);
}
ChangeMoney.cs (An example of an 'effect')
[System.Serializable]
public class ChangeMoney : Effect {
public int amount;
public override void Apply(Character character)
{
character.currentMoney += amount;
}
}
Important part of my trait editor script
public class Trait Editor : EditorWindow
{
// Make the window and controls blah blah //
void OnGUI()
{
if(GUILayout.Button("Add Change Money"))
{
ChangeMoney newEffect = ScriptableObject.CreateInstance<ChangeMoney>();
newEffect.amount = amount;
string path = AssetDatabase.GetAssetPath(traitList);
AssetDatabase.AddObjectToAsset(newEffect, path);
traitList.traitList[viewIndex-1].effects.Add(newEffect);
AssetDatabase.SaveAssets(); // Save the asset.
}
}
Now I am 100% sure there is some extra code in an around there especially the saving of the object and adding it to the list seems redundant. Any help to making that neater/nicer would be helpful but this seems to work so I wanted to help someone else out.
No 'Type Mismatch' errors and it works with this:
public void TraitTick()
{
foreach(Trait t in traits)
{
foreach(Effect e in t.effects)
{
e.Apply(this);
}
}
}
Here is what is looks like in the inspector:
Your answer
Follow this Question
Related Questions
how to access the buttons when the AR camera is turned on. 0 Answers
Randomly changing between two tags using coroutine 2 Answers
Heyzap Listener: delegate randomly becoming null at run time (Android) 1 Answer
Similar movement to a game (look description) 1 Answer
Unity for Ubuntu 14.04 64 bits 1 Answer