Hello,
I’m Peter (18 ) and I’m currently in the seccond year of Game Design in Groningen (Netherlands, if my English sucks; that why). Since Unity is given free our teacher figured out that we should start using the Unity engine for our 3D projects. In the previous project we had to create a 3D character and let it walk in the Unity engine, this (of course) wasn’t that hard to accomplish.
In our new project we need to make a 3D museum about a certain art-style. (we’ve chosen pop-art).
As our school almost only requires that we’re good designers and the other students don’t like scripting anyway so there we also have almost no support for scripting. So all the museums will almost certainly have camera’s that go through walls etc.
As i’m also very interested in scripting and I want to make a good “engine” for our 3D museum. First of all I wanted to make sure that my camera wont go behind walls, witch of course happens fast when you’re inside a building. I already managed to fix this problem with this script:
A modified the script and changed the following:
- The script originally only moves the camera behind the target when pressing a button or moving the mouse, now it will move behind the target also when moving nothing.
- When you pressed the left and right mouse btn it was supposed to walk ore something but the character would only be sliding in one direction. So I’ve managed to get rid of that part.
As our museum is also going to have a couple of paintings I want to try if I can make the following:
- When getting close to a painting the words “Press space to watch closer” should appear in the screen.
- When pressing space the camera should move smoothly to a position exactly in front of the painting, when pressing space again it should move back to the character.
Of course I wont expect from you guys to just give me such a script because I do have to learn something of it. I have in my head how it probably should work so ill explain it here.
- First I have to make a trigger witch I can place close to an painting, this trigger has to trigger a function witch lets the words appear in my screen. This function also has to check if I press the space btn.
- When the space btn is pressed it needs to changes the target of the camera in the “WowCamera.cs” to the painting.
- When the camera is pointed at the painting it still has to check if the space btn is pressed but then it has to change the target of the camera in the “WowCamera.cs” back to the character.
At least, I hope that the camera will smoothly move to the new target by it self and that I won’t have to modify that part.
I really hope that someone is interested in helping me out, because my teacher are not able to
Greetings,
Peter aka Crash-Konijn
WowCamera.cs
using UnityEngine;
using System.Collections;
public class WowCamera : MonoBehaviour
{
public Transform target;
public float targetHeight = 1.7f;
public float distance = 5.0f;
public float offsetFromWall = 0.1f;
public float maxDistance = 20;
public float minDistance = .6f;
public float xSpeed = 200.0f;
public float ySpeed = 200.0f;
public float targetSpeed = 5.0f;
public int yMinLimit = -80;
public int yMaxLimit = 80;
public int zoomRate = 40;
public float rotationDampening = 3.0f;
public float zoomDampening = 5.0f;
public LayerMask collisionLayers = -1;
private float xDeg = 0.0f;
private float yDeg = 0.0f;
private float currentDistance;
private float desiredDistance;
private float correctedDistance;
void Start ()
{
Vector3 angles = transform.eulerAngles;
xDeg = angles.x;
yDeg = angles.y;
currentDistance = distance;
desiredDistance = distance;
correctedDistance = distance;
// Make the rigid body not change rotation
if (rigidbody)
rigidbody.freezeRotation = true;
}
void Update()
{
Vector3 vTargetOffset;
// Don't do anything if target is not defined
if (!target)
return;
// If either mouse buttons are down, let the mouse govern camera position
if (Input.GetMouseButton(0))
{
xDeg += Input.GetAxis ("Mouse X") * xSpeed * 0.02f;
yDeg -= Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;
}
//Reset the camera angle and Rotate the Target Around the World!
else if (Input.GetMouseButton(1))
{
float targetRotationAngle = target.eulerAngles.y;
float currentRotationAngle = transform.eulerAngles.y;
xDeg = Mathf.LerpAngle (currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
target.transform.Rotate(0,Input.GetAxis ("Mouse X") * xSpeed * 0.02f,0);
xDeg += Input.GetAxis ("Mouse X") * xSpeed * 0.02f;
}
// otherwise, ease behind the target if any of the directional keys are pressed
else
{
float targetRotationAngle = target.eulerAngles.y;
float currentRotationAngle = transform.eulerAngles.y;
xDeg = Mathf.LerpAngle (currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
}
yDeg = ClampAngle (yDeg, yMinLimit, yMaxLimit);
// set camera rotation
Quaternion rotation = Quaternion.Euler (yDeg, xDeg, 0);
// calculate the desired distance
desiredDistance -= Input.GetAxis ("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs (desiredDistance);
desiredDistance = Mathf.Clamp (desiredDistance, minDistance, maxDistance);
correctedDistance = desiredDistance;
// calculate desired camera position
vTargetOffset = new Vector3 (0, -targetHeight, 0);
Vector3 position = target.position - (rotation * Vector3.forward * desiredDistance + vTargetOffset);
// check for collision using the true target's desired registration point as set by user using height
RaycastHit collisionHit;
Vector3 trueTargetPosition = new Vector3 (target.position.x, target.position.y + targetHeight, target.position.z);
// if there was a collision, correct the camera position and calculate the corrected distance
bool isCorrected = false;
if (Physics.Linecast (trueTargetPosition, position, out collisionHit, collisionLayers.value))
{
// calculate the distance from the original estimated position to the collision location,
// subtracting out a safety "offset" distance from the object we hit. The offset will help
// keep the camera from being right on top of the surface we hit, which usually shows up as
// the surface geometry getting partially clipped by the camera's front clipping plane.
correctedDistance = Vector3.Distance (trueTargetPosition, collisionHit.point) - offsetFromWall;
isCorrected = true;
}
// For smoothing, lerp distance only if either distance wasn't corrected, or correctedDistance is more than currentDistance
currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp (currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance;
// keep within legal limits
currentDistance = Mathf.Clamp (currentDistance, minDistance, maxDistance);
// recalculate position based on the new currentDistance
position = target.position - (rotation * Vector3.forward * currentDistance + vTargetOffset);
transform.rotation = rotation;
transform.position = position;
//Move the Player with left right button press together
/*if(Input.GetMouseButton(1)&Input.GetMouseButton(0))
{
float targetRotationAngle = target.eulerAngles.y;
float currentRotationAngle = transform.eulerAngles.y;
xDeg = Mathf.LerpAngle (currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
target.transform.Rotate(0,Input.GetAxis ("Mouse X") * xSpeed * 0.02f,0);
xDeg += Input.GetAxis ("Mouse X") * targetSpeed * 0.02f;
target.transform.Translate(Vector3.forward * targetSpeed * Time.deltaTime);
}*/
}
/**
* Camera logic on LateUpdate to only update after all character movement logic has been handled.
*/
void LateUpdate ()
{
}
private static float ClampAngle (float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp (angle, min, max);
}
}
ThirdPersonWalker.js
private var speed = 0.0;
var speedRun = 12.0;
var speedWalk = 6.0;
var jumpSpeed = 2.0;
var gravity = 20.0;
private var moveDirection = Vector3.zero;
private var grounded : boolean = false;
function FixedUpdate() {
if (grounded) {
// We are grounded, so recalculate movedirection directly from axes
//transform.position.z = 0;
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton ("Jump")) {
moveDirection.y = jumpSpeed;
animation.Play ("jump");
}
else if (Input.GetButton ("Vertical") || Input.GetButton ("Horizontal"))
{
if (Input.GetButton ("Run"))
{
speed = speedRun;
animation.CrossFade ("run");
}
else {
speed = speedWalk;
animation.CrossFade ("walk");
}
}
else if (Input.GetButton ("Custom"))
{
animation.CrossFade ("custom");
}
else {
animation.CrossFade ("idle");
}
}
// Apply gravity
moveDirection.y -= gravity * Time.deltaTime;
// Move the controller
var controller : CharacterController = GetComponent(CharacterController);
var flags = controller.Move(moveDirection * Time.deltaTime);
grounded = (flags CollisionFlags.CollidedBelow) != 0;
}
@script RequireComponent(CharacterController)