Skip to content

Commit

Permalink
Objects can now hold more than one activity; first prototype of LotMa…
Browse files Browse the repository at this point in the history
…nager collates master list of activities
  • Loading branch information
BlackJar72 committed Sep 4, 2024
1 parent 1657a4e commit 3492300
Show file tree
Hide file tree
Showing 15 changed files with 246 additions and 37 deletions.
3 changes: 2 additions & 1 deletion Scripts/Characters/AI/Simple/Activity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

namespace CharacterModel {

public class Activity : MonoBehaviour {
[System.Serializable]
public class Activity {

public ENeeds need;
public float satisfaction;
Expand Down
37 changes: 37 additions & 0 deletions Scripts/Characters/AI/Simple/ActivityChoice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.AI;

namespace CharacterModel {


[System.Serializable]
public class ActivityChoice : IComparer<ActivityChoice>, System.IComparable<ActivityChoice> {
[SerializeField] public Activity activity;
//[SerializeField] public AbstractNeedEvaluator evaluator;
public float desirability = 0; // This is to be calculated during decision making, not preset as data

// Getting and setting desirability
public float GetDesirability(CoreNeeds needs, float situation)
=> needs.GetNeed(activity.need).Evaluator.GetDesirability(this, needs.GetNeed(activity.need), situation);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetDesirability(CoreNeeds needs, float situation) {
needs.GetNeed(activity.need).Evaluator.SetDesirability(this, needs.GetNeed(activity.need), situation);
}

// Comparisons -- desirability is the basis, since the more desirable choices willl be preferred
// Compare() and CompareTo() are set up so that sort functions will place higher desirability on top
public static bool operator >(ActivityChoice a, ActivityChoice b) => a.desirability > b.desirability;
public static bool operator <(ActivityChoice a, ActivityChoice b) => a.desirability < b.desirability;
public static bool operator >=(ActivityChoice a, ActivityChoice b) => a.desirability >= b.desirability;
public static bool operator <=(ActivityChoice a, ActivityChoice b) => a.desirability <= b.desirability;
public int Compare(ActivityChoice a, ActivityChoice b) {
return -a.desirability.CompareTo(b.desirability); // Should I do this, or use arithmetic?
}
public int CompareTo(ActivityChoice other) {
return -desirability.CompareTo(other.desirability); // Should I do this, or use arithmetic?
}
}

}
11 changes: 11 additions & 0 deletions Scripts/Characters/AI/Simple/ActivityChoice.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 11 additions & 27 deletions Scripts/Characters/AI/Simple/ActivityChooser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,13 @@ namespace CharacterModel {

public class ActivityChooser : MonoBehaviour
{

[System.Serializable]
public class ActivityChoice : IComparer<ActivityChoice>, System.IComparable<ActivityChoice> {
[SerializeField] public Activity activity;
//[SerializeField] public AbstractNeedEvaluator evaluator;
public float desirability = 0;
public float GetDesirability(CoreNeeds needs, float situation)
=> needs.GetNeed(activity.need).Evaluator.GetDesirability(this, needs.GetNeed(activity.need), situation);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetDesirability(CoreNeeds needs, float situation) {
needs.GetNeed(activity.need).Evaluator.SetDesirability(this, needs.GetNeed(activity.need), situation);
}
public static bool operator >(ActivityChoice a, ActivityChoice b) => a.desirability > b.desirability;
public static bool operator <(ActivityChoice a, ActivityChoice b) => a.desirability < b.desirability;
public static bool operator >=(ActivityChoice a, ActivityChoice b) => a.desirability >= b.desirability;
public static bool operator <=(ActivityChoice a, ActivityChoice b) => a.desirability <= b.desirability;
public int Compare(ActivityChoice a, ActivityChoice b) {
return -a.desirability.CompareTo(b.desirability); // Should I do this, or use arithmetic?
}
public int CompareTo(ActivityChoice other) {
return -desirability.CompareTo(other.desirability); // Should I do this, or use arithmetic?
}
}


[SerializeField] List<ActivityChoice> choices = new List<ActivityChoice>();
[SerializeField] Character character;
[SerializeField] CoreNeeds needs;

private float activityTimer = 0;
private bool atLoction = false;
private bool ready = false;

//Testing Stuff
[SerializeField] GameObject testingPlaceShower;
Expand All @@ -57,6 +33,7 @@ void Start()
// FIXME/TODO: This ultimately needs to be removed, but first it must be replaced with a call from outside
void Update()
{
if(!ready) return;
if(activityTimer <= 0) {
currentChoice = Choose();
testingPlaceShower.transform.position = currentChoice.actorLocation.position;
Expand All @@ -66,13 +43,13 @@ void Update()
else needs.Situation = 0.2f;
navAgent.SetDestination(currentChoice.actorLocation.position);
atLoction = false;
testingPlaceShower.SetActive(false);
} else {
//FIXME: Remember, in the real game anything similar must use worled (simulation) time, not engine game time!
if(atLoction) {
transform.rotation = currentChoice.actorLocation.rotation;
activityTimer -= Time.deltaTime;
needs.GetNeed(currentChoice.need).AddSafe((currentChoice.satisfaction / currentChoice.timeToDo)
* Time.deltaTime);
* Time.deltaTime);
} else {
atLoction = navAgent.remainingDistance < 0.1f;
testingPlaceShower.SetActive(atLoction);
Expand Down Expand Up @@ -126,6 +103,13 @@ public Activity Choose() {
}


public void AssignChoices(List<ActivityChoice> availableChoices) {
choices.Clear();
foreach(ActivityChoice choice in availableChoices) choices.Add(choice);
ready = true;
}



}

Expand Down
32 changes: 32 additions & 0 deletions Scripts/Characters/AI/Simple/ActivityHolder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.AI;

namespace CharacterModel {


[System.Serializable]
public class ActivityHolder : MonoBehaviour {

[SerializeField] ActivityChoice[] activities;

public ActivityChoice[] Activities => activities;
public ActivityChoice GetActivityChoice(int n) => activities[n];
public Activity GetActivity(int n) => activities[n].activity;


public void AddActivities(ref List<ActivityChoice> mainList) {
foreach(ActivityChoice activity in Activities) {
mainList.Add(activity);
}
}


// TODO: It seems I need more, but not sure what yet

}



}
11 changes: 11 additions & 0 deletions Scripts/Characters/AI/Simple/ActivityHolder.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Scripts/Characters/Character.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@ public class Character : MonoBehaviour {
[SerializeField] EmotionalState emotions;
[SerializeField] Preferences preferences;

[SerializeField] ActivityChooser ai;

public static ulong IDCount => idCounter;

public Personality Persona => personality;
public CoreNeeds Needs => needs;
public EmotionalState Emotions => emotions;
public Preferences prefs => preferences;

public ActivityChooser AI => ai; // FIXME? TODO? Should it really be part of a bigger AI module?


/// <summary>
/// Set the ID of a new character; this should be done when character is created and should never change
Expand Down
4 changes: 2 additions & 2 deletions Scripts/Characters/State/AbstractNeedEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ namespace CharacterModel {

public abstract class AbstractNeedEvaluator : ScriptableObject {

public abstract float GetDesirability(ActivityChooser.ActivityChoice choice, Need need, float extraData = 0f);
public abstract float GetDesirability(ActivityChoice choice, Need need, float extraData = 0f);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public abstract void SetDesirability(ActivityChooser.ActivityChoice choice, Need need, float extraData = 0f);
public abstract void SetDesirability(ActivityChoice choice, Need need, float extraData = 0f);
}

}
4 changes: 2 additions & 2 deletions Scripts/Characters/State/DepletingNeedEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ namespace CharacterModel {
[CreateAssetMenu(menuName = "Character Engine/AI/Depleting Need Evaluator", order = 1001, fileName = "DepletingEvaluator")]
public class DepletingNeedEvaluator : AbstractNeedEvaluator {

public override float GetDesirability(ActivityChooser.ActivityChoice choice, Need need, float unused = 0f) {
public override float GetDesirability(ActivityChoice choice, Need need, float unused = 0f) {
SetDesirability(choice, need);
return choice.desirability;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void SetDesirability(ActivityChooser.ActivityChoice choice, Need need, float unused = 0f) {
public override void SetDesirability(ActivityChoice choice, Need need, float unused = 0f) {
choice.desirability = (choice.activity.satisfaction
+ (choice.activity.satisfaction / (choice.activity.timeToDo + 5)))
* need.GetDrive() * Need.TIME_SCALE;
Expand Down
4 changes: 2 additions & 2 deletions Scripts/Characters/State/SituationalNeedTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ namespace CharacterModel {
[CreateAssetMenu(menuName = "Character Engine/AI/Situational Need Evaluator", order = 1002, fileName = "SituationalEvaluator")]
public class SituationalNeedTracker : AbstractNeedEvaluator {

public override float GetDesirability(ActivityChooser.ActivityChoice choice, Need need, float situation) {
public override float GetDesirability(ActivityChoice choice, Need need, float situation) {
SetDesirability(choice, need, situation);
return choice.desirability;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void SetDesirability(ActivityChooser.ActivityChoice choice, Need need, float situation) {
public override void SetDesirability(ActivityChoice choice, Need need, float situation) {
choice.desirability = (choice.activity.satisfaction - situation) * need.GetDrive() * Need.TIME_SCALE;
}

Expand Down
8 changes: 5 additions & 3 deletions Scripts/Characters/State/VitalNeedTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,20 @@ namespace CharacterModel {
[CreateAssetMenu(menuName = "Character Engine/AI/Vital Need Evaluator", order = 1003, fileName = "VitalEvaluator")]
public class VitalNeedTracker : AbstractNeedEvaluator {

public override float GetDesirability(ActivityChooser.ActivityChoice choice, Need need, float situation) {
public override float GetDesirability(ActivityChoice choice, Need need, float situation) {
SetDesirability(choice, need, situation);
return choice.desirability;
}


[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void SetDesirability(ActivityChooser.ActivityChoice choice, Need need, float situation) {
public override void SetDesirability(ActivityChoice choice, Need need, float situation) {
choice.desirability = (choice.activity.satisfaction - situation) * need.GetDrive() * Need.TIME_SCALE;
choice.desirability *= choice.desirability;
}


public float GetDrive(ActivityChooser.ActivityChoice choice, Need need) {
public float GetDrive(ActivityChoice choice, Need need) {
return (Mathf.Max((need.DriveOrigin - need.Value), 0f)
/ Mathf.Clamp(need.Value - 0.2f, 0.01f, 0.4f) * need.Importance);
}
Expand Down
72 changes: 72 additions & 0 deletions Scripts/Characters/Trait/Skills.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using CharacterEngine;


namespace CharacterModel {

[System.Serializable]
public class Skills {
[SerializeField] Skill[] coreSkills = new Skill[17];





}



#region SkillEnums
public enum ECoreSkills {
//Physical
Athletics = 0,
Dancing = 1,
Driving = 2,
MartialArts = 3,

//Creative
Art = 4,
Music = 5,
Writing = 6,

//Intellectual
Science = 7,
Mechanical = 8,
Computers = 9,
Gaming = 10,

//Social
Charm = 11,
Performance = 12,
Persuasion = 13,

//Practical
Business = 14,
Cooking = 15,
Housekeeping = 16,
Naturalist = 17
}


public enum EChildSkills {
Physical = 0,
Creative = 1,
Intellectual = 2,
Social = 3,
Practical = 4
}


public enum EHiddenSkills {
Physical = 0,
Creative = 1,
Intellectual = 2,
Social = 3,
Practical = 4
}
#endregion


}
11 changes: 11 additions & 0 deletions Scripts/Characters/Trait/Skills.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions Scripts/Characters/World/LotManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.AI;

namespace CharacterModel {


[System.Serializable]
public class LotManager : MonoBehaviour {
[SerializeField] List<ActivityHolder> usableObjects;
[SerializeField] List<Character> characters;

private List<ActivityChoice> choices;

// Start is called before the first frame update
void Start() {
choices = new List<ActivityChoice>();
foreach(ActivityHolder usableObject in usableObjects) {
usableObject.AddActivities(ref choices);
}
foreach(Character character in characters) {
character.AI.AssignChoices(choices);
}
}

/*// Update is called once per frame
void Update() {
}*/
}

}
Loading

0 comments on commit 3492300

Please sign in to comment.