Newer
Older
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TaskCharakterAnimation : MonoBehaviour
{
public GameObject walkAroundObject;
public GameObject player;
public float radiusAroundObject;
public float talkingZoneDistance;
private Animator anim;
private Transform currentTransform;
private float currentDistance;
//When changing walking/standing/happy booleans -> the state-variables in the animationController must also be changed
//For change of the task-character movements, maybe the transitions in the animationController have also to be adjusted
private float walkingTime = 5;
private bool walking = true;
private float standingTime = 3;
private bool standing = false;
private float timer = 0;
private bool rotate = false;
private float nextRotation = 0;
private float rotationUnits = 0;
private float rotationTime = 2;
private bool happy = false;
private bool happyAnimationDone = false;
private float happyTimer = 0;
private float happyTime = 7.5f;
private static bool taskCharacterAddressed = false;
// Start is called before the first frame update
void Start()
{
anim = GetComponent<Animator>();
currentTransform = GetComponent<Transform>();
}
// Update is called once per frame
void Update()
{
//Do nothing else than the animation if animationController is in happy-State
if (happy)
{
this.happyTimer += Time.deltaTime;
if (happyTimer >= happyTime)
stopHappy();
RaycastHit hit;
Ray ray = new Ray(player.transform.position, player.transform.forward);
int layerMask = LayerMask.GetMask("TalkingZone"); //only hit TalkingZone
//If Player is in TalkingZone: TaskCharacter should look to the Player, stop walking and enable enter-key for talking
if (Physics.Raycast(ray, out hit, talkingZoneDistance, layerMask))
{
this.walking = false;
this.standing = true;
this.timer = 0;
//Change boolean for switching to Standing-State in AnimationController
anim.SetBool("standing", true);
//Enable enter-key for talking for Charakter-Dialog
setPlayerInTalkingZone(true);
//Face walkAroundObject to Player (but only on y-Axis, so ignore x-and z-axis)
currentTransform.LookAt(new Vector3(player.transform.position.x, currentTransform.position.y, player.transform.position.z));
if(checkGameSolved() && taskCharacterAddressed && !happyAnimationDone)
{
startHappy();
happyAnimationDone = true;
}
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
return;
}
else {
//disable enter-key for talking
setPlayerInTalkingZone(false);
}
this.timer += Time.deltaTime;
if (rotate)
{
if (this.timer <= rotationTime)
{
//Change to random direction after standing-state
currentTransform.RotateAround(currentTransform.position, Vector3.up, rotationUnits);
}
else {
//After rotating: Change to Walking-State
rotate = false;
this.timer = 0;
//Change boolean for switching to Walking-State in AnimationController
anim.SetBool("standing", false);
}
}
else
{
//If walking-time is over -> Change to standing-state
if (walking && !standing)
{
if (this.timer >= this.walkingTime)
{
this.walking = false;
this.standing = true;
this.timer = 0;
//Change boolean for switching to Standing-State in AnimationController
anim.SetBool("standing", true);
}
}
else
{
//If standingTime is over: Change to walking-state, but before set rotate=true for rotating before walking
if (this.timer >= this.standingTime)
{
this.standing = false;
this.walking = true;
this.timer = 0;
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
//Calculate distance from tree, so that the TaskCharacter only walks in a specific radius around the tree
//so that the player always knows where he is
currentDistance = (currentTransform.position - walkAroundObject.transform.position).magnitude;
//Turn on the radius-edges around the radiusAroundObject
if (currentDistance > radiusAroundObject)
{
//Rotate Towards tree if radiusAroundObject is out of radius
//Rotate randomly between +/-5° towards the radiusAroundObject
int temp = Random.Range(0, 5);
int positive = (int)Random.Range(0, 2);
//Calculate NextRotation towards radiusAroundObject
nextRotation = Vector3.Angle(currentTransform.forward, (walkAroundObject.transform.position-currentTransform.position).normalized);
if (positive == 0)
nextRotation -= temp;
else
nextRotation += temp;
}
else
{
//Rotate Character randomly if radiusAroundObject is inside the radius
//Rotate inside the range of -180° and 180° because a normal human would turn e.g. -60° instead of 240°
nextRotation = Random.Range(0, 180);
int positive = (int)Random.Range(0, 2);
if (positive == 0)
nextRotation *= -1;
}
rotationUnits = nextRotation / (rotationTime/Time.deltaTime);
rotate = true;
}
}
}
}
public bool checkGameSolved()
{
return FactManager.gameSolved();
}
public void startHappy()
{
//Set Variable in animationController to change the state
anim.SetBool("solved", true);
happy = true;
//Trigger for CharacterDialog
CommunicationEvents.gameSucceededEvent.Invoke();
//StartHappyTimer
happyTimer = 0;
public void stopHappy()
{
//Set Variable in animationController to change the state
anim.SetBool("solved", false);
happy = false;
resetToStart();
}
public void resetToStart() {
//On Reset: Player must go into walking state, because it could be that after the happy/running-animation the player is
//out of radius and rotates -> AnimationController StateMachine always changes into walking-state after hyppAnimation
walking = false;
standing = true;
rotate = false;
nextRotation = 0;
rotationUnits = 0;
playerInTalkingZone = false;
}
//Static Method for CharacterDialog
public static bool getPlayerInTalkingZone() {
return playerInTalkingZone;
}
//Static Method for CharacterDialog
public static void setPlayerInTalkingZone(bool value) {
playerInTalkingZone = value;
}
//Static Method for CharacterDialog
public static bool getTaskCharacterAddressed()
{
return taskCharacterAddressed;
}
//Static Method for CharacterDialog
public static void setTaskCharacterAddressed(bool value)
{
taskCharacterAddressed = value;
}