Showing posts with label Unity3D. Show all posts
Showing posts with label Unity3D. Show all posts

Tuesday, April 9, 2013

Camera Drag and Zoom with Mouse in Unity 3D

The script is easy and descriptive, it is the result of some searching and modification.

  • Press the left mouse button and drag to move, and use mouse scroll wheel to zoom in and out.
  • The zooming code can work for both orthogonal and perspective but I've been using and testing it in orthogonal mode. 
  • Modify the public values to fit in your game.

** Just drag the script to your camera and it will work! **

C# code
[CameraDragZoom.cs]
using UnityEngine;
using System.Collections;

public class CameraDragZoom : MonoBehaviour {
    
    public float dragSpeed = -10;
    public int minX = -892;
    public int maxX = 1111;
    public int minZ = -880;
    public int maxZ = 1145;
    
    public int bottomMargin = 80; // if you have some icons at the bottom (like an RPG game) this will help preventing the drag action at the bottom
    
    public float orthZoomStep = 10.0f;
    public int orthZoomMaxSize = 500;
    public int orthZoomMinSize = 300;
    
    private bool orthographicView = true;
    private Vector3 dragOrigin;
    
    // Update is called once per frame
    void Update () {
        moveCamera();
        zoomCamera();
    }
    
    void moveCamera()
    {
        if (Input.GetMouseButtonDown(0))
        {    
            dragOrigin = Input.mousePosition;
            return;
        }

        if (!Input.GetMouseButton(0)) return;
        
        if(dragOrigin.y <= bottomMargin) return;
        
        Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - dragOrigin);
        Vector3 move = new Vector3(pos.x * dragSpeed, 0, pos.y * dragSpeed);
                
        if(move.x > 0)
        {
            if(!isWithinRightBorder())
                move.x =0;
        }
        else
        {
            if(!isWithinLeftBorder())
                move.x=0;
        }
        
        if(move.z > 0)
        {
            if(!isWithinTopBorder())
                move.z=0;
        }
        else
        {
            if(!isWithinBottomBorder())
                move.z=0;
        }
            
        
        transform.Translate(move, Space.World);
    }
    
    void zoomCamera()
    {
        if(!isWithinBorders())
            return;
        
        // zoom out
        if (Input.GetAxis("Mouse ScrollWheel") <0)
        {
            if(orthographicView)
            {
                if (Camera.main.orthographicSize <=orthZoomMaxSize)
                    Camera.main.orthographicSize += orthZoomStep;
            }
            else
            {
                if (Camera.main.fieldOfView<=150)
                       Camera.main.fieldOfView +=5;
            }
        }
        // zoom in
        if (Input.GetAxis("Mouse ScrollWheel") > 0)
           {
            if(orthographicView)
            {
                if (Camera.main.orthographicSize >= orthZoomMinSize)
                     Camera.main.orthographicSize -= orthZoomStep;            
            }
            else
            {
                if (Camera.main.fieldOfView>2)
                    Camera.main.fieldOfView -=5;
            }
           }
    }
    
    bool isWithinBorders()
    {
        return ( isWithinLeftBorder() && isWithinBottomBorder() && isWithinRightBorder() && isWithinTopBorder() );
    }
    
    bool isWithinLeftBorder()
    {
        Vector3 currentTopLeftGlobal = Camera.main.ScreenToWorldPoint(new Vector3(0,0,0));
        if(currentTopLeftGlobal.x > minX)
            return true;
        else
            return false;
        
    }
    
    bool isWithinRightBorder()
    {
        Vector3 currentBottomRightGlobal = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width,0,0));
        if(currentBottomRightGlobal.x < maxX)
            return true;
        else
            return false;
    }
    
    bool isWithinTopBorder()
    {
        Vector3 currentTopLeftGlobal = Camera.main.ScreenToWorldPoint(new Vector3(0,Screen.height,0));
        if(currentTopLeftGlobal.z < maxZ)
            return true;
        else
            return false;
    }
    
    bool isWithinBottomBorder()
    {
        Vector3 currentBottomRightGlobal = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width,0,0));
        if(currentBottomRightGlobal.z > minZ)
            return true;
        else
            return false;
    }
}



Friday, February 15, 2013

Unity3D: Rotate Object to Face Another

I've been working on porting an HTML5 demo to Unity3D, when I stopped for more than a day just to rotate a cannon towards a point!

I have to admit that Unity3D is great, but it can turn simple tasks into complex ones for no reason. Anyways, after some time with Quaternion class and Lerp function and searching for online solutions, I decided to go back to basics. The problem with Lerp is that it forces rotation in a certain time. So the cannon will rotate 30 degrees in -say- 5 seconds, and will also rotate 60 degrees in 5 seconds, which is not logical. And to solve this I have to do some extra math.

So what did I do? I just rotated with a certain amount of degrees per second (using rotate() function) , and checked if the angle between my cannon and the target is within the allowed range to shoot (with a cross product of two vectors). That's it!

The code works as follows:
- If cannon is in attack mode, rotate towards target point with a fixed speed.
- The cannon object has a child object called nose, it is a point representing the missile start point and used for measuring the angle between the cannon-nose vector and nose-target vector.
- If the angle is within an accepted value, stop and fire.
- The assumption is that the game is in the Z-plane and the cannon rotates around the Z axis.

public float rotationSpeed = 30;
public float rotationErrorFraction = 0.01f;
bool attackMode = false;
Vector3 targetPoint;

void Update()
{
 
 if(attackMode)
 {   
  Transform nose = transform.FindChild("Nose");

  // check if cannon looks at target
  Vector3 targetDirection = (targetPoint - nose.position);
  targetDirection.z = 0;
  Vector3 cannonDirection = (nose.position - transform.position);
  cannonDirection.z = 0;
  
  targetDirection.Normalize();
  cannonDirection.Normalize();
  Vector3 cross = Vector3.Cross(cannonDirection, targetDirection);
  float crossZ = cross.z;

  // If within range, fire. Else, rotate again.
  if(crossZ < rotationErrorFraction && crossZ > -rotationErrorFraction)
  {
   // fire
   if(missile)
   {
    Instantiate(missile, nose.position, nose.rotation);
   }
   attackMode = false;
  }
  else
  {
   if(crossZ > 0)
    transform.Rotate(Vector3.forward, Time.deltaTime*rotationSpeed);
   else
    transform.Rotate(Vector3.back, Time.deltaTime*rotationSpeed);
  }
 }
}

Tuesday, January 17, 2012

Book Review: Google SketchUp for Game Design: Beginner's Guide




Today I'm writing a review on a very special book: Google SketchUp for Game Design: Beginner's Guide, by Robin de Jongh, Packt Publishing. I really enjoyed this book, and to be clear and organized, I'll write my review as definite points (as usual =) ).

Pros:

  • As the book title mentioned, it is a guide for game design and beginners. So the book did not only go from bottom up in Google SketchUp, but also went to explain the basics of other applications that can get involved in the game design process like GIMP, and even introduced one of the best game engines: Unity.
  • All tools and websites introduced are free, or have trial versions/accounts.
  • The book author stressed on a very important thing: honesty, and the cover image is an example of this honesty. Because what you see on this cover is what you get and can do yourself using what you learned in Google SketchUp.
  • The way the author explains is not boring or lengthy. But on the contrary, it was very smooth, interesting, and straight to the point.
  • The author stressed on introducing the basic and important features of each applications without getting deep, which I considered it a very nice method in dealing with a beginner in any application. Beside some tips and tricks, and notes on how bigger companies do this work and manage such tasks.
  • The book in general was like a quick tour in the world of assets and game design, opening some doors I might not see if I just go to learn Google SketchUp alone.


Cons:

  • The websites and links provided inside the book were not all working. Some links were removed and some had different sub-directories, but somehow I managed to get to most of them by a quick search.
  • The author sometimes missed some small details that -for a lazy beginner- can be crucial to get a step done. Some small details like the order of marking objects or how to use a certain tool. But the athor has indicated that this book needs some work, so there is no place for laziness.


All in all, I would recommend this book for reading, whether you are using Google SketchUp for game asset design, game level design, or even as an architect.