- Home /
Drawing architecture normally, but with key items only visible in front of the player
Sorry if the question was hard to understand, but I don't know how to describe it myself. I want to make a game with the camera over the map(but not isometric), with architecture drawn all the time, but with enemies, key items, only drawn in a field in front of the controlled model. Something like in the "Monaco" video game, but in 3D.
Answer by supernat · Jun 12, 2014 at 08:44 PM
Uploading an image of what you want would go a long way, but I think I understand. You want the 3rd person view over the player's character, but you want to only see (from the 3rd person camera) what the player would see if they were walking on the terrain in the game. Correct?
It's a simple matter of trigonometry. You need to project a cone forward from the player, test all enemies in the scene to lie either inside or outside of that cone, and enable or disable their renderers. Make sure the cone is projected in the local body coordinates of the player so that when the player character turns left or right, the cone is always coming out of his/her eyes. When you do the dot product, go back to world coordinates for ease. I chose a cone because it can be easily represented with a single direction cosine value.
If you take the dot product between two normalized vectors, you end up with the cosine of the angle between them (called the direction cosine). It's always between -1 and +1 where 0 means the two lines are exactly 90 deg apart (orthogonal), +1.0 means they are completely parallel, and -1 means they are 180 degrees apart. If you take the dot product of the player's line of sight (the character down on the terrain I mean), with the vector created from the player to a given enemy, you can do a simple check if that value is within a tolerance. Don't take the acos(dot prod) to get the angle, that's wasteful, just compare the direction cosine itself. Something like this:
// Run this somewhere in a script located on the main character game object
Vector3 playerLOS = transform.forward;
Vector3 enemyVector = (enemy.transform.position - transform.position).normalized;
float dirCos = Vector3.Dot(playerLOS, enemyVector);
if (dirCos > 0.8f)
// Turn on enemy renderer
else
// Turn off enemy renderer
There's a simplified approach but more costly in terms in method calls, because it adds extra normalization calls and computing acos which are expensive, but you could say something like this:
if (Vector3.Angle(transform.forward, enemy.transform.position - transform.position) < 15.0f)
// Turn on enemy renderer
else
// Turn off enemy renderer
You'll want to do these operations continuously but intelligently. You could split the entire set of enemies up into 10 groups for instance, especially if you have a lot of them, and each frame in the Update() method of your class, only process turning the enemy renders on and off for 1 group at a time. You could process them all in a separate thread or even just do one enemy at a time in a coroutine if you don't have a lot of enemies. That's up to you. Also, you may want to only process them when an enemy is actually moving or the player is moving.
EDIT: A couple of other notes. the value I used above of 0.8 = cos(angle), so take acos(0.8) to see what angle that is. If you process turning the renderers on/off in a thread, it has to be thread safe, because you can't change actual components or their values from a non-main thread without crashing, so you'd have to buffer up the list. This all really depends on how many enemies you will have active in the world, as you could just process them all each frame, but if you do it for mobile, it's one way to save a little processing time. The cone will truly behave like a cone, meaning enemies that aren't near the axis of the cone (i.e. airplanes flying high up) will be culled with this method. To get those type of enemies, you'd want to create to planes, sort of like the left and right walls of a view frustum, and then determine if targets lie in front of or behind those planes (they must be in front of both).
Your answer
Follow this Question
Related Questions
ThirdPersonShooter-Camera-Script Optimization 0 Answers
third person camera script? 1 Answer
reduce speed at which main camera rotates... 1 Answer
third person camera 1 Answer
Toggling between two cameras/camera fix on fallout. 1 Answer