Some treatment methods of TPS camera and camera occlusion

Source: Internet
Author: User

Feed

Third-person cameras have a very wide range of cameras to implement today in a third-person shooter game.



If you are not familiar with camera control, it is recommended to take a look at the previous post fps camera.


Control ideas

The mouse controls yaw and pitch, adding a distance variable to record the distance between the character and the camera. Get the camera's position through yaw and pitch.

Finally add a right displacement and an upward displacement, placing the character in the left-hand position of the screen.


Transform.localeulerangles = new Vector3 (-rotationy, RotationX, 0); CharacterModel.transform.forward = new Vector3 ( Transform.forward.x, Charactermodel.transform.forward.y, transform.forward.z); target.forward = new Vector3 ( Transform.forward.x, 0, transform.forward.z); float Yaw = rotationx;float Pitch = rotationy;float yawred = Mathf.deg2rad * (yaw-90f); float pitchred = Mathf.deg2rad * PITCH; Vector3 Direction = new Vector3 (-mathf.cos (yawred) * Mathf.cos (pitchred),-mathf.sin (pitchred), Mathf.sin (yawred) * Mathf.cos (pitchred)); transform.position = target.transform.position + Distance * direction;transform.position + = Transform.right + transform.up;

Here, the camera only controls the model's rotation.

Direction is the direction of the camera's ray through yaw and pitch's calculated role.


the handling of some problems

Animation processing of characters running in oblique direction

Usually in TPS games, the back of the character is always on the camera. When the player wants the character to go in a diagonal direction, it is not possible to directly play the character forward animation, this time need to give the role model an additional angle offset, the offset is determined by the player's input.



The code is as follows

CharacterModel.transform.forward = new Vector3 (transform.forward.x, Charactermodel.transform.forward.y, TRANSFORM.FORWARD.Z); if (charactermodel.transform.parent.getcomponent<character> (). Characterfpanimation.extrarotation = = 0) {Extrarot = Mathf.lerp (Extrarot, 0f, ten * time.deltatime);} Else{extrarot = Mathf.lerp (Extrarot, charactermodel.transform.parent.getcomponent<character> (). Characterfpanimation.extrarotation, ten * time.deltatime);} quaternion targetrotation = characterModel.transform.rotation * Quaternion.angleaxis (Extrarot, vector3.up); CharacterModel.transform.rotation = targetrotation;

Added lerp to make the turn more smooth.



Wall occlusion

Environmental masking is a third-person camera that often encounters problems, and here are a few common methods.

The solution is a ray detection that moves the camera to a position that is not obscured.

In a tutorial on the Unity website, the process is to slowly move the camera up until you see the character (the scene of the game has no ceiling)

 BOOL Viewingposcheck (Vector3 checkpos) {Raycasthit hit; If a raycast from the check position to the player hits something ... if (Physics.raycast (Checkpos, Player.positio N-checkpos, out hit, relcameraposmag))//... if it's not the player ... if (hit.transform! = Playe                R)//This position isn ' t appropriate.                return false;        If we haven ' t hit anything or we've hit the player, this is an appropriate position.        Newpos = Checkpos;    return true;        } void Smoothlookat () {//Create a vector from the camera towards the player.                Vector3 relplayerposition = player.position-transform.position;        Create a rotation based on the relative position of the player being the forward vector.                quaternion lookatrotation = quaternion.lookrotation (relplayerposition, vector3.up); Lerp the camera ' s rotation between it's current Rotation and the rotation that looks at the player.    Transform.rotation = Quaternion.lerp (transform.rotation, lookatrotation, smooth * time.deltatime); }

This is the deal in the update.

  void Fixedupdate () {///The position of the camera is the relative position of the camera from the P        Layer.                Vector3 Standardpos = player.position + relcamerapos;        The Abovepos is directly above the player at the same distance as the standard position.                Vector3 Abovepos = player.position + vector3.up * RELCAMERAPOSMAG;        An array of 5 points to check if the camera can see the player.                vector3[] checkpoints = new vector3[5];        The first is the standard position of the camera.                Checkpoints[0] = Standardpos;        The next three is 25%, 50% and 75% of the distance between the standard position and Abovepos.        CHECKPOINTS[1] = Vector3.lerp (Standardpos, Abovepos, 0.25f);        CHECKPOINTS[2] = Vector3.lerp (Standardpos, Abovepos, 0.5f);                CHECKPOINTS[3] = Vector3.lerp (Standardpos, Abovepos, 0.75f);        The last is the Abovepos. CHECKPOINTS[4] = Abovepos;               Run through the check points ... for (int i = 0; i < checkpoints.length; i++) { If the camera can see the player ... if (Viewingposcheck (Checkpoints[i]))//... break fr                Om the loop.        Break        }//Lerp the camera's position between it ' s current position and it's new position.                Transform.position = Vector3.lerp (transform.position, Newpos, smooth * time.deltatime);        Make sure the camera was looking at the player.    Smoothlookat (); }

From the head of the character's foot, there were radiographic tests in four places, and the final result was this.



Similarly, you can pull the camera to the front of the blocked wall.


The code for the detection is as follows

void Sheltertest () {raycastresult result = new Raycastresult (); Float characterheight = Gamemanager.getinstance (). Character.height * 0.4F; Vector3 Targetheadpos = new Vector3 (target.position.x, TARGET.POSITION.Y + characterheight, target.position.z); ray[] testrays = new RAY[5]; Testrays[0] = new Ray (targetheadpos, transform.position + 0.8f * transform.right + 0.5f * transform.up-targetheadpos); TESTRAYS[1] = new Ray (targetheadpos, transform.position + 0.8f * transform.right-0.5f * transform.up-targetheadpos); TESTRAYS[2] = new Ray (Targetheadpos, transform.position-0.8f * transform.right + 0.5f * transform.up-targetheadpos);  TESTRAYS[3] = new Ray (Targetheadpos, transform.position-0.8f * transform.right-0.5f * transform.up-targetheadpos); TESTRAYS[4] = new Ray (transform.position, transform.position-targetheadpos); float castdist = (transform.position-targ Etheadpos). magnitude;float[] dists = new FLOAT[5]; for (int i = 0; i < 5; i++) {if (Raycasthelper.raycastall (TestraYs[i], Castdist, True, Gamemanager.getinstance (). Character.floormask, out result) {Debug.drawline (Targetheadpos, Result.point, color.red);d ists[i] = vector3.distance (Result.point, targetheadpos);} Else{debug.drawline (Targetheadpos, Targetheadpos + castdist * testrays[i].direction, Color.Blue);d ists[i] = castDist;}} float minDist0 = mathf.min (Dists[0], dists[1]); float minDist1 = Mathf.min (dists[2], dists[3]); float minDist2 = Mathf.min ( MinDist0, minDist1); float mindist = Mathf.min (MinDist2, dists[4]); transform.position = Targetheadpos + mindist * testrays [4].direction.normalized;}

5 rays were used to detect, in order to avoid the problem of the FOV through the wall. Note that the camera is fired from the character.


The solution of two translucent objects in the middle occlusion



Use Raycast to detect, and then dynamically replace the material can be.


Three-method to redraw characters using stencil

For stencil buffer do not understand, please refer to this article: stencil buffer

This part of the pixel can be processed by ztest the stencial of the masked part of the role. You can either draw it in a single color, draw it transparently, or draw a glowing stroke.

The simple effect is as follows:




Here are three pass processing, the first to draw the use of Ztest write stencil

Shader "Custom/player" {Properties {_maskvalue ("Mask Value", int) = 2_maintex ("Base (RGB)", 2D) = "White" {}}subshader {T AGS {"Rendertype" = "Opaque"}lod 200Stencil {Ref [_maskvalue]comp alwayspass replacezfail Keep    }cgprogram#pragma Surface Surf lambertsampler2d _maintex;struct Input {float2 uv_maintex;}; void Surf (Input in, InOut surfaceoutput o) {half4 c = tex2d (_maintex, In.uv_maintex); O. Albedo = C.rgb;o. Alpha = C.A;} ENDCG} FallBack "Diffuse"}

And a shader to clear ztest.

Shader "Custom/clearzbuffer" {Properties {_maintex ("Base (RGB) Gloss (A)", 2D) = "White" {}}subshader {Tags {"Rendertype "=" Transparent "  " Queue "=" transparent+100 "}lod 80ColorMask 0ZTest greaterzwrite oncgprogram#pragma Surface surf Lambertsampler2d _maintex;struct Input {float2 uv_maintex;}; void Surf (Input in, InOut surfaceoutput o) {  Half4 c = tex2d (_maintex, In.uv_maintex); O. Albedo = Half4 (1,0,0,1); O. Alpha = 0.3;} ENDCG} FallBack "Diffuse"}

Finally, a shader is used to process the pixels marked by the stencil.

Shader "Custom/stenciltransparent" {Properties {    _maskvalue ("Mask Value", int) = 2_maintex ("Base (RGB)", 2D) = "White "{}_transval (" Transparency Value ", Range (0,1)) = 1.0  _coloradd (" Color (ADD, RGB) ", color) = (0.5,0,0)}subshader {Ta GS {"Rendertype" = "Opaque" "Queue" = "transparent+100"}lod 80Stencil {Ref [_maskvalue]comp notequalpass keep}ztest Lequalzwrite onblend srcalpha Oneminussrcalphablendop addcgprogram#pragma surface surf lambertsampler2d _MainTex;fixed _transval;  Half4 _coloradd;struct Input {  float2 uv_maintex;}; void Surf (Input in, InOut surfaceoutput o) {  Half4 c = tex2d (_maintex, In.uv_maintex);//o.albedo = C.rgb * HALF4 (1,0 , 0,1);//o.alpha = 1;o. Albedo = C.rgb * _coloradd;o. Alpha = _transval;} ENDCG} FallBack "Diffuse"}

Occlusion processing is not a good way to say which is best, and can be used for mixed use to achieve the best results.
Reference

Real-time cameras:a guide for Game designers and developers

Unity Tutorial Stealth-http://unity3d.com/learn/tutorials/projects/stealth-tutorial-4x-only

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Some treatment methods of TPS camera and camera occlusion

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.