Post screenshots of your path visualisation? Have you added some colour? Do you have a crazy path? What Gizmos did you use?
I was wondering why we drew spheres to indicate the waypoints when thats built into unity.
so only thing worth indicating then is the lines - also, you can pick alternative shapes that even include the namesWhat did you use to draw the names?
Not sure I know what you mean by the spheres being built into unity?
In the inspector right next to the enabled tick box you see like a grey. Iāve with a black arrow on it. Click it and pick from various colours and shapes to auto put coloured doodads on your things like waypoints. The big lozenges are coloured with names.
No coding at all comes with unity
yeah, thatās a handy feature I use for labeling empties in the scene, or things like FX. But I like the automation of having it be in the code of the WaypointPath parent.
I figured out how to do it myself yesterday, but your way is a lot neater!
var waypoint = transform.GetChild(i).position;
if (i == 0)
{
firstWaypoint = waypoint;
previousWaypoint = waypoint;
}
else if (i + 1 == transform.childCount)
{
Gizmos.color = Color.red;
Gizmos.DrawLine(firstWaypoint, waypoint);
Gizmos.DrawLine(previousWaypoint, waypoint);
}
else
{
Gizmos.color = Color.red;
Gizmos.DrawLine(previousWaypoint, waypoint);
previousWaypoint = waypoint;
}
Nice! Didnāt know you could do that.
I presume the consistency could get screwed up if you create new sub game objects though, right?
Hi Sam,
I donāt know if itās just me, but this many extractions makes me confused and I think itās harder to understand the code later on.
I fell like reading those long contracts with many references to other paragraphs that makes you back and forth on the reading.
My approach to this problem was:
private void OnDrawGizmos()
{
Gizmos.color = Color.cyan;
for (int i = 0; i < transform.childCount; i++)
{
Gizmos.DrawSphere(transform.GetChild(i).position, 0.2f);
if (i == transform.childCount-1)
{
Gizmos.DrawLine(transform.GetChild(i).position, transform.GetChild(0).position);
continue;
}
Gizmos.DrawLine(transform.GetChild(i).position, transform.GetChild(i + 1).position);
}
}
Do you see any issues or advises for me?
Yeah, thatās a personal preference thing. The kind of thing you have to work out with coworkers and come to a compromiseš
Snippet of my PatrolPath class. To be honest half way through the section I stopped following the videos and did my own thing (i.e. allowing for multiple classes [fighter, mage, etc]). Would love if I could share the GitLab link and if any of the instructors could give some feedback.
using UnityEngine;
namespace RPG.Control {
public class PatrolPath : MonoBehaviour {
public Vector3 GetWaypointPosition(int index) => transform.GetChild(index).position;
private Vector3 GetNextWaypointPosition(int index) => transform.GetChild(index == transform.childCount - 1 ? 0 : index + 1).position;
private void OnDrawGizmos() {
const float waypointGizmoRadius = 0.3f;
for (int i = 0; i < transform.childCount; i++) {
Gizmos.color = Color.red;
Gizmos.DrawSphere(GetWaypointPosition(i), waypointGizmoRadius);
Gizmos.DrawLine(GetWaypointPosition(i), GetNextWaypointPosition(i));
}
}
}
}
Also, in the video you mentioned modular arithmetics, but I fail to see how to use that here. Mind elaborating?
Share away! Would love to see it.
Sure thing. Here you go: https://gitlab.com/baruchvlz/rpg_course
Feel free to be as ruthless as you want with the feedback
Iāve been trying to make enemy field of view and hearing which attract nearby enemies
all i managed to make with the help of unity assets so far is this.
Iām facing a problem with SphereCollider the Player treat it as collider and when i click on it the Player go and attack the enemy.
Iām using SphereCollider with range of 10 as enemy hearing and i listen for animation.
Now each time i click and the raycastHit hits the SphereCollider the player go and attack the enemy.
I tried to ignore the SphereCollider in InteractWithCombat() function by using hit.collider is SphereCollider
now the player goes at the edge of the sphereCollider this is the issue iām facing so far.
the code is too complicated to understand fully but this course helped me to understand the code iām using from the unity assets for field of view and making it work in the game.
i was hoping to make my own code for field of view and hearing which attract nearby enemies.
but i couldnāt it was so difficult. it would be a great help if some one could point me in the right direction.
and is it possible to make the environment make the sound not just SphereCollider and listen for ontriggerStay or enter, i want when the Player hit and interactble object it makes a sound that the enemy could hear, it would be a great if some one could help me in these issues.
I know this is a lot of questions but i hope someone could help me with it.
1- SphereCollider problem ?
2- from where to start to write my own code of field of view and hearing from scratch ?
3- how can i make the environment make the sounds when player trigger it ?
Iām not familiar with the code youāre using to give the enemies a field of view. This makes it difficult to diagnose and solve the problem youāre havingā¦
Hereās what I think is going on:
The detection system youāre using uses a sphere collider to detect if the player has entered the range of the enemy, it then checks to see if the enemy is looking in the playerās direction. This causes the Raycast in the player controller to pick up the enemy as a target in the SphereColliderās range instead of the capsule collider.
This is one of the trickier aspects of integrating 3rd party code into a system. There can be major conflicts between the way that the systems work.
Rather than ruling out by checking collider type, try comparing the distance from the hit.point to the actual enemy location Vector3.distance(hit.point, hit.transform.position). If itās greater than sayā¦ 2 then ignore the hit.
In terms of writing your own field of viewā¦ consider the AI code that is provided by the course. This detection scheme is a bit simpler, relying on the distance from the enemy to the player. The field of view can be determined by comparing the angle between the vector between the enemyās transform.forward and the vector from the player to the enemy (player.transform.position - transform.position). If itās less than the field of view angle, the enemy can āseeā the player. You can improve on this by raycasting from the enemyās position to the playerās position. If the result is the player then the enemy can āseeā the player, if not, then his field of view is blocked by an obstacle.
āHearingā is even easier, when the player makes a noise, find all the Enemy Ai controllers, and inform them the player has made a noise. The Enemy AI controller then determines if itās close enough by comparing distance to itās hearing distance.
For making sounds in the environment, see the lecture Sound Effects and Unity Events (https://www.gamedev.tv/courses/637539/lectures/11879580 if youāre using our platformās course). Youāll have to create an event for the sound effect, attach the sound effect to the event, and fire that event when you wish to make the sound effect. Itās a bit of extrapolation from the material already provided in the lecture.
Thank you for taking the time to clarify this. your answer is really helpful.
the part related to SphereCollider problem, I still donāt understand how to solve it.
in the code we search for ray cast that collides with objects and get the ones that has the component CombatTarget.
now the Sphere is a collider and if some how ignored it by checking its sphere or by checking if the distance is > 2.
still donāt know where to add to the code to make it work.
private bool InteractWithCombat()
{
RaycastHit[] hits = Physics.RaycastAll(GetMouseRay());
foreach(RaycastHit hit in hits)
{
CombatTarget target = hit.transform.GetComponent<CombatTarget>();
// here i put the is Sphere check or the distance > 2 then continue;
if (!fighter.CanAttack(target)) continue;
if (Input.GetMouseButtonDown(0))
{
fighter.Attack(target);
}
return true;
}
return false;
}
this is the function iām using if i add the solution which look for is SphereCollider then continue it will keep looking its like an obstacle the same for distance > 2 also it works as obstacle
so i still canāt figure it. tried it by layerMask but didnāt work.
private bool InteractWithCombat()
{
RaycastHit hits = Physics.RaycastAll(GetMouseRay());
foreach(RaycastHit hit in hits)
{
CombatTarget target = hit.transform.GetComponent<CombatTarget>();
if(Vector3.Distance(hit.point, hit.transform.position)>2) continue;
if (!fighter.CanAttack(target)) continue;
if (Input.GetMouseButtonDown(0))
{
fighter.Attack(target);
}
return true;
}
return false;
}
Yes i did this the player doesnāt go inside the ShpereCollider if i clicked near the enemy
the player go to the edge of the sphere and stops there.
and if iām inside the sphere and tried to click in the range of the sphere the player wonāt move
is it possible to ignore one of the colliders for raycast ?
as now enemy has 2 colliders on the parent object capsule and sphere
I disabled all the other scripts and commented all the extra code i written, in order to know the where is the problem. but still the same result.
Unfortunately, no, there isnāt. A GameObject is on a specified layer, and all of the colliders on that GameObject are part of that layer and collision.
It is possible to put the collider on a CHILD GameObject and change the layer of the child GameObject, but this would require some reworking of the code.
This is why Iām not strongly recommending this 3rd party system for integration into the RPG game weāve set up.
ok thank you.