Newer
Older
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TaskCharakterAnimation : MonoBehaviour
{
public GameObject walkAroundObject;
public GameObject player;
public float radiusAroundObject;
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
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
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 static bool playerInTalkingZone = false;
// Start is called before the first frame update
void Start()
{
anim = GetComponent<Animator>();
currentTransform = GetComponent<Transform>();
CommunicationEvents.PushoutFactEvent.AddListener(startHappy);
CommunicationEvents.PushoutFactEndEvent.AddListener(stopHappy);
}
// Update is called once per frame
void Update()
{
//Do nothing else than the animation if animationController is in happy-State
if (happy)
return;
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, 5f, 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
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
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));
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;
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
//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 void startHappy(Fact startFact)
{
//Set Variable in animationController to change the state
anim.SetBool("solved", true);
happy = true;
}
public void stopHappy(Fact startFact) {
//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;
}
}