Showing posts with label unity3D. Show all posts
Showing posts with label unity3D. Show all posts

Friday, January 4, 2019

How to show FPS in Unity3D C#

Showing FPS can be helpful when you’re on a handheld device and gauging performance.

Sometimes you may need to throttle quality for device depending on the performance.

This code is how you display FPS in C# for a mono behaviour script.


  1. void Update () {
  2. deltaTime += (Time.deltaTime - deltaTime) * 0.1f;
  3. float fps = 1.0f / deltaTime;
  4. Debug.Log(Mathf.Ceil(fps).ToString() + “ FPS”);
  5. }

Thursday, May 12, 2016

Determine if device is an Amazon/Fire TV in Unity 3D

Often when you use the same apk for google play and amazon stores and you need to determine at run time whether your device is running Android OS or a Kindle on Fire OS. You may need to even further determine if the device is an Amazon Fire TV or Android TV app.

In Unity3D you can often use SystemInfo.deviceModel, and put it into if/then or case and set appropriate flags. Then you can implement google play, game circle, forward to the appropriate store for rating an app, etc.:

public static string getDevice() {
if (  SystemInfo.deviceModel.ToLower().Contains("aftb")) {
isAmazon = true;
return "Fire TV";
}
        if (  SystemInfo.deviceModel.ToLower().Contains("amazon")) {
isAmazon = true;
return SystemInfo.deviceModel;
}
isAmazon = false;
return SystemInfo.deviceModel;
}

Tuesday, April 26, 2016

Creating a MusicController Module in Unity 3D C#

In Unity3D or any game engine you sometimes need music to play across multiple scenes. To accomplish this in Unity3D you need to create a MusicController GameObject that doesn't destroy on load. Below I do this with a Singleton Class that retains from scene to scene! Game.music is a static boolean field that tells rest of the system that music is enabled. On this controller I have an array of AudioClip[]. which I can have songs in ogg or mp3 format.




using UnityEngine;
using System.Collections;
using System;
using System.IO;
using Prime31;

public class MusicController : MonoBehaviour {

#region Music
public static MusicController Instance { get; private set; }
public AudioClip[] Tracks;
int currentTrack=0;
public void Awake() {
if (!Game.music) {
Instance = null;
Destroy(gameObject);
return;
}
if (Instance!=null) {
Destroy(gameObject);
GetComponent<AudioSource>().Stop();
}
if (Instance==null) {
Instance = this;
DontDestroyOnLoad(this.gameObject);
}
}
public string trackName() {
string x = "";
if (GetComponent<AudioSource>().clip!=null)
x = GetComponent<AudioSource>().clip.name;
return x;
}

public void playRandomTrack(bool t) {

GetComponent<AudioSource>().Stop();
GetComponent<AudioSource>().enabled = true;
int x = UnityEngine.Random.Range(0,Tracks.Length);
GetComponent<AudioSource>().clip = Tracks[x];
GetComponent<AudioSource>().Play();
currentTrack = x;
if (GUI.Instance!=null)
GUI.Instance.ShowTextToast("Track: " + trackName(),5f);
}


public void playRandomTrack() {

playRandomTrack(true);
}

public void Start() {

if (Game.music) {
Instance = null;
playRandomTrack();
Awake();
return;
}
}

public void Update() {

if (!Game.music) {
Instance = null;
Destroy(gameObject);
return;
}

if (!GetComponent<AudioSource>().isPlaying && GetComponent<AudioSource>().clip!=null)

playRandomTrack();
if (Game.gameOver) {
GetComponent<AudioSource>().volume = 0.75f;
} else if (Game.shouldBegin)  {
GetComponent<AudioSource>().volume = 0.25f;
} else GetComponent<AudioSource>().volume = 0.75f;
}
#endregion

}

Saturday, January 30, 2016

Observer Pattern in Unity3D's C#

Can't tell you how often I use observers, and delegates and events in C# when using Unity3D. Say you have a boolean value called isWinner in your Game Class. If you want to see if that bool value has became true in a different class you need to subscribe using an observer and observable. Since isWinner is boolean, a different class called Leaderboards needs to run a method that increments a GameCenter leaderboard. You accomplish this through the Observer Pattern and Delegates.

In a Game class:

private static bool _isWinner = false;
public static bool isWinner {
get { return _isWinner; }
set { _isWinner = value;
if (_isWinner) {
initiateWinner();
}
}
}

public delegate void Winner();
public static event Winner initiateWinner;

        public static void finishGame() {
                 isWinner = true;
        }

In a Leaderboard class:

void OnEnable() {
Game.initiateWinner += doWin;
}

void OnDisable() {
Game.initiateWinner -= doWin;
}

void doWin() {
                // do your gamecenter, social, prime31 code here
}


From above it's easy to assess that is happening. isWinner is changed, and the event initateWinner() is initiated. Then on the Leaderboard class it's observed and calls doWin();.

Tuesday, January 19, 2016

Change Resolution pixels of iOS Game using Unity3D 5.3.1f1 in Xcode 7.x

To change the resolution in Unity 5.3.1f1 is difficult in iOS when it comes to granularity of the device. Prior to 5.3.x, you could simply put in different modes for resolution. Auto Performance, Native Resolution, and Auto Quality were some of the few.  With the new version you can not adjust this so it requires that your hands get a bit dirty.

See below in DisplayManager.mm. look for UnityScreenScaleFactor:

Modify as below:

extern "C" float UnityScreenScaleFactor(UIScreen* screen)
{
// we should query nativeScale if available to get the true device resolution
// this way we avoid unnecessarily large frame buffers and downscaling.
// e.g. iPhone 6+ pretends to be a x3 device, while its physical screen is x2.6 something.
    
    /* Amit's custom code screen size */
    float resMult = 0.75f;
    switch(UnityDeviceGeneration())
    {
        case deviceiPadPro1Gen:     resMult = 0.6f;     break;
        case deviceiPhoneUnknown:   resMult = 0.75f;    break;
        case deviceiPhone6:         resMult = 0.75f; break;
        case deviceiPhone7:         resMult = 0.75f; break;
        case deviceiPhone6Plus:     resMult = 0.6f;     break;
        case deviceiPhone6S:        resMult = 0.75f; break;
        case deviceiPhone6SPlus:    resMult = 0.6f;     break;
        case deviceiPhone4:         resMult = 0.6f; break;
        case deviceiPad3Gen:        resMult = 0.5f; break;
        case deviceiPad4Gen:        resMult = 0.5f; break;
        case deviceiPadAir1:        resMult = 0.5f; break;
        case deviceiPadAir2:        resMult = 0.5f; break;
        case deviceiPadMini2Gen:    resMult = 0.5f; break;
        case deviceiPadMini3Gen:    resMult = 0.5f; break;
        case deviceiPadUnknown:     resMult = 0.5f;     break;
        default:                    resMult = 0.8f;     break;
    }

    if([screen respondsToSelector:@selector(nativeScale)])
{
// On AppleTV screen.nativeScale returns NaN when device is in sleep mode
if (isnan(screen.nativeScale))
return 1.0f;
else
return screen.nativeScale * resMult;
}
return screen.scale * resMult;

}


As you can see above, the resMult is what you multiply the resolution accordingly. For example if you take a 0.5f multiplyer on an iPad Retina (2048x1536) it'll turn your resolution to 1/2 or 0.5 of it which is essentially 1024x768.

Why you may ask would you want to do this? Speed, simply. Some games run entirely to slow in full resolution with Unity3D. It is optimal to use a multiplyer and scale down for older devices with AA or AAA games graphics.

Lazy Initialization of Singleton in C# Unity

Singleton's are bad design patterns because they are essentially global variables or static classes vs individually static variables. Though we are taught to stay away from them in gaming they can come in handy, especially in Unity. I usually make my GameControllers singleton because there is essentially no chance that I'd need more than once instance of it.

Lazy initialization is nice because it'll initialize your instance when you need it, as you need it in the lifetime of your class.

As follows:

using UnityEngine;
using System.Collections;
using System;
using System.IO;
using Prime31;

public class GameController : Game {
public static GameController Instance { get; private set; }

#region Unity Behaviour
public void Awake () {
Instance = this;
        }
#endregion

}

You can design the class to inherit attributes (as mine does above from the Abstract Game Class). To reference the class from external classes you'd use GameController.Instance.*.  To access the internal variables when you use this Singleton you'll have to declare them as public.  In lieu of making public variables it's Ideally best to make them private and use getters and setters.

You can also pass Singleton's into methods and functions if you say for arguments sake have 2 classes inheriting from Game, both Singletons. You can decide which Singleton you want to pass in runtime, granted that both classes have the same method "someMethod()" in them publically. This can be done in runtime as follows:

     public void callMethod(Game p) {
         p.someMethod();
     }

    public void test() {
         callMethod(GameController.Instance);
    }

Though many argue Singleton is arguably an Anti-pattern, you can make the counter argument because of the usefulness and ubiquity of rampant use, it's legitimate in any programmer's arsenal.

Wednesday, April 22, 2015

How to make camera shake in Unity3D (javascript)

Making the Camera shake in Unity3D can add much needed dramatic effects to your game. To implement you need to manipulate position and rotation in random ranges. See below:

var originPosition:Vector3;
var originRotation:Quaternion;
var shake_decay: float;
var shake_intensity: float;

function ShakeCustom(x:float, y:float){
   originPosition = transform.position;
   originRotation = transform.rotation;
   shake_intensity = x;
   shake_decay = y;
}

function LateUpdate() {
if(shake_intensity > 0){
      transform.position = originPosition + Random.insideUnitSphere * shake_intensity;
      transform.rotation = Quaternion(
      originRotation.x + Random.Range(-shake_intensity,shake_intensity)*.2,
      originRotation.y + Random.Range(-shake_intensity,shake_intensity)*.2,
      originRotation.z + Random.Range(-shake_intensity,shake_intensity)*.2,
      originRotation.w + Random.Range(-shake_intensity,shake_intensity)*.2);
      shake_intensity -= shake_decay;
  }
}

Thursday, January 16, 2014

Unity3D C# Enemy Find nearest Player Script

In this script which you attach to the Enemy Objects, you may find the nearest object Tagged "Player". The Enemy faces the Player, and chases within a proximity, with a given frequency. See below:

/// <summary>
/// AI character controller.
/// Just A basic AI Character controller
/// will looking for a Target and moving to and Attacking
/// </summary>

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(CharacterSystem))]

public class AICharacterController : MonoBehaviour {

    public GameObject ObjectTarget;
    public string TargetTag = "Player";
    private CharacterSystem character;
    private int aiTime = 0;
    private float scanFrequency = 1.0f;
    private int aiState = 0;

    void Start () {
        character = gameObject.GetComponent<CharacterSystem>();
        InvokeRepeating ("ScanForTarget",0,scanFrequency);
    }
   
    void ScanForTarget() {
        ObjectTarget = GetNearestTaggedObject();
    }

    public GameObject GetNearestTaggedObject () {
        var nearestDistanceSqr = Mathf.Infinity;
        GameObject nearestObj = null;

        foreach (var obj in GameObject.FindGameObjectsWithTag(TargetTag)) {

            var objectPos = obj.transform.position;
            var distanceSqr = (objectPos - transform.position).sqrMagnitude;
           
            if (distanceSqr < nearestDistanceSqr) {
                nearestObj = obj;
                nearestDistanceSqr = distanceSqr;
            }
        }
        return nearestObj;
    }

    public float DistanceSquaredTo(GameObject source, GameObject target) {
        return Vector3.SqrMagnitude(source.transform.position - target.transform.position);
    }

    void Update () {
            //if (GameObject.Find("CharacterDakota").GetComponent<CharacterStatus>().HP > 0) {
           
        if (GameObject.Find("GameManager").GetComponent<GameManager>().Playing) {

            var direction = Vector3.zero;
            if(aiTime<=0){
                aiState = Random.Range(0,4);
                aiTime = Random.Range(10,100);
            }else{
                aiTime--;
            }
            if(ObjectTarget){
                //ObjectTarget = GameObject.FindGameObjectWithTag(TargetTag);   
                float distance = Vector3.Distance(ObjectTarget.transform.position,this.gameObject.transform.position);
               
                if(distance<=2){
                    transform.LookAt(ObjectTarget.transform.position);
                    if(aiTime<=0){
                        if(aiState == 1){
                            character.Attack();
                        }
                    }
                }else{
                    if(aiState == 1){
                        transform.LookAt(ObjectTarget.transform.position);
                        direction = this.transform.forward;
                        direction.Normalize();
                        character.Move(direction);
                    }
                }
               
            }else{
                ScanForTarget();
            }
        }
    }
}

Thursday, August 8, 2013

Modify Terrain Data in Unity3D during Runtime

How do you change the Pixel Error, Base Map Distance, Cast Shadows, Tree Distance and other settings from runtime, not in inspector using UnityScript or C#?

It's relatively easy when you reference the Component on Terrain. This script should work:

Terrain.activeTerrain.GetComponent.<Terrain>().heightmapPixelError = 200;
for(var gameObj : Terrain in GameObject.FindObjectsOfType(Terrain)) {
        gameObj.GetComponent.<Terrain>().heightmapPixelError = 200;
        gameObj.GetComponent.<Terrain>().basemapDistance = 200;
        gameObj.GetComponent.<Terrain>().castShadows = false;
        gameObj.GetComponent.<Terrain>().treeDistance = 500;
        gameObj.GetComponent.<Terrain>().detailObjectDistance = 25;

      }

Wednesday, March 27, 2013

Change Frame Rate in Unity3D

The FPS framerate in Unity3D is easier than ever with Unity3D 3.5+.

Below is the JS and the C# code counterpart:


    function Awake () {
        // Make the game run as fast as possible in the web player
        Application.targetFrameRate = 300;
    }
public class example : MonoBehaviour {
    void Awake() {
        Application.targetFrameRate = 300;
    }
}

Tuesday, March 12, 2013

Vibrate Handheld in Unity3D

This simple script tells the Game/App from Unity to shake/vibrate the Device if iOS/Android. If the device doesn't support vibrate, it'll simply do nothing!:

#if UNITY_IPHONE | UNITY_ANDROID

      Handheld.Vibrate();

#endif

Friday, January 25, 2013

Playing Music from iOS Music Playlist with Unity3D


With this simple coding you can play a playlist on your device from your Unity3D Game. Why license royalties when you can get the user to do it for you per individual basis.  I am using this in my game Snowboarding+ (see gameplay demo above). If there is no music on your device it'll finally play the local music in your Unity 3D app. This plays the playlist called Snowboarding+

in AppController.mm (also add MediaPlayer.framework):

#include <MediaPlayer/MediaPlayer.h>


- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
[self playMusic];
}


- (void) playMusic {
  // Instantiate a music player
    MPMusicPlayerController *appPlayer = [MPMusicPlayerController applicationMusicPlayer];
    
    // Shuffle all songs
    [appPlayer setShuffleMode:MPMusicShuffleModeSongs];
    
    // Assume we will not find our playlist
    BOOL playlistFound = NO;
    
    // Get a collection of all playlists on the device
    MPMediaQuery *playlistsQuery = [MPMediaQuery playlistsQuery];
    NSArray *playlists = [playlistsQuery collections];
    NSString *plus;
    plus = @"all";
    // Check each playlist to see if it is the right one
    for (MPMediaPlaylist *playlist in playlists) {
        NSString *playlistName = [playlist valueForProperty: MPMediaPlaylistPropertyName];
        if ([playlistName isEqualToString:@"Snowboarding+"]) {
            // Add the playlist to the player's queue and get out of here
            [appPlayer setQueueWithItemCollection:playlist];
            playlistFound = YES;
            plus = @"snowboarding+";
            break;
        }
    }
    
    // If no playlist found, just play All playlist
    if (!playlistFound) {
        for (MPMediaPlaylist *playlist in playlists) {
            NSString *playlistName = [playlist valueForProperty: MPMediaPlaylistPropertyName];
            if ([playlistName isEqualToString:@"All"]) {
                // Add the playlist to the player's queue and get out of here
                [appPlayer setQueueWithItemCollection:playlist];
                playlistFound = YES;
                plus = @"all";
                break;
            }
            else
            {
                //IF NO ALL play a random song
                [appPlayer setQueueWithQuery: [MPMediaQuery songsQuery]];
                plus = @"random";
            }
        }

    }
    
    // Start playing from the beginning of the queue
    [appPlayer play];
    
    if (appPlayer.playbackState == MPMusicPlaybackStatePlaying)
{                
UnitySendMessage("Camera", "isPlaying","TRUE");
NSLog(@"%@ is playing",plus);}
            else
{
                UnitySendMessage("Camera", "isPlaying","FALSE");
NSLog(@"internal music from Unity3D App is playing");}

}
}

In Unity 3D add the following to the Script on your Camera or any game object from above:

var isMusicPlaying: boolean = false;

@script RequireComponent(AudioSource)

function Start() {
    // Delay a clip by 10 sec (44100 samples)
  #if UNITY_EDITOR || UNITY_ANDROID || UNITY_OSX
      audio.Play(44100 * 5);     
   #endif

}

function isPlaying(message:String)
 {
  if (message == "TRUE") {isMusicPlaying = true; audio.Stop(); }
  if (message == "FALSE") {isMusicPlaying = false;  audio.Play();  }

  Debug.Log("Is the Music Playing from Device? " + message);
 }

Friday, January 18, 2013

Player Movement for Simple Air Hockey Game

This segment is for simple movement for a player in an Air Hockey Game on a 3D plane. You move mouse x and y and the y corresponds on the z plane.  This is from my Air Hockey 3D game available currently in the Android, iOS and Mac App Stores.

var other : GameObject ;
var dist : float;
var hitSound : AudioClip;
var spark : Transform;
var offset : Vector2 = Vector2.zero;
function spark1()
{
Instantiate (spark, transform.position, transform.rotation);
yield WaitForSeconds(0.5);
Destroy(GameObject.Find("Sparks(clone)"));
}
function Update () {
if (Time.timeScale != 0) {
other = GameObject.Find ("Sphere");
var Menu = GameObject.Find("Menu");
var script : menu = Menu.GetComponent(menu);
  var hit : RaycastHit;  
    var up = Vector3 ((transform.position.x - other.transform.position.x) * -1 , 0,
    (transform.position.z - other.transform.position.z) * -1 );
 
    if (Input.GetAxis("Mouse Y") > 0)     dist = 0.3 +  (Input.GetAxis("Mouse Y") / 8 ) + other.rigidbody.velocity.magnitude / 80;   else
    dist = 0.15 + other.rigidbody.velocity.magnitude / 80;
 
   Debug.DrawRay(transform.position, up , Color.green);
 
    if(Physics.Raycast(transform.position, up , hit, dist)){
       
      if(hit.collider.gameObject.name == "Sphere"){
      spark1();
      AudioSource.PlayClipAtPoint(hitSound, transform.position);
      other.rigidbody.AddForce(  up * (other.rigidbody.velocity.magnitude + 20 ),  ForceMode.Impulse);
      }
    }
if (script.singlePlayer) {
Screen.showCursor = false; #if UNITY_EDITOR
if (Input.mousePosition.x >  0  &&  Input.mousePosition.x < Screen.width)
transform.position.x = Input.mousePosition.x / (Screen.width / 2.4);
if (Input.mousePosition.y >  0 && Input.mousePosition.y < (Screen.height * 0.7)) {
if (transform.position.z < 2.194 && transform.position.z > 0) {
transform.position.z =  (Input.mousePosition.y * 0.7) / ((Screen.height * 0.7) / (3.18));
}
else if (transform.position.z >= 2.194) transform.position.z = 2.193;
 else if (transform.position.z <= 0) transform.position.z = 0.0001;
}
//Debug.Log(transform.position.z);
#elif UNITY_IPHONE || UNITY_ANDROID
if(Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved) {
if (Input.mousePosition.x >  0  &&  Input.mousePosition.x < Screen.width)
transform.position.x = Input.mousePosition.x / (Screen.width / 2.4);
if (Input.mousePosition.y >  0 && Input.mousePosition.y < (Screen.height * 0.7)) {
if (transform.position.z < 2.194 && transform.position.z > 0) {
transform.position.z =  (Input.mousePosition.y * 0.7) / ((Screen.height * 0.7) / (3.18));
}
else if (transform.position.z >= 2.194) transform.position.z = 2.193;
 else if (transform.position.z <= 0) transform.position.z = 0.0001;
}
}
#endif
}
}
}

 



Submit Scores and Points to Game Center in Unity3D

This simple script is how to submit scores and points to the Game Center from a Unity3D Game. People use the prime31 plugin, and pay the extra money, which dumbfounds me. Just do it yourself! I've done both JS and C# implementations of the same code... Here it goes in JavaScript:



#if UNITY_IPHONE
import UnityEngine.SocialPlatforms;
#endif

//These next two methods show the leaderboard

function DoLeaderboard () {
#if UNITY_IPHONE
Social.localUser.Authenticate (ProcessAuthentication);
#endif
}

function ProcessAuthentication (success: boolean) {
#if UNITY_IPHONE
    if (success) {
        Debug.Log ("Authentication successful");
    Social.CreateLeaderboard();
Social.CreateLeaderboard().id = "YourLeaderBoardID";
Social.ShowLeaderboardUI();
    }
    else
        Debug.Log ("Failed to authenticate");
#endif
}


//these next two methods report a score to the leaderboard

function reportScoreToBoard() {
#if UNITY_IPHONE
Social.localUser.Authenticate (ReportScore);
#endif
}


function ReportScore (success: boolean) {
#if UNITY_IPHONE
    if (success) {
        
        Debug.Log ("Authentication successful");
   
    Social.CreateLeaderboard();

Social.CreateLeaderboard().id = "YourLeaderBoardID";
Social.ReportScore(PlayerPrefs.GetInt("timeElapsed"),"YourLeaderBoardID",  function(result) {
        if (result)
            Debug.Log ("Successfully reported timeElapsed, Virgin:" + PlayerPrefs.GetInt("timeElapsed"));
        else
            Debug.Log ("Failed to report timeElapsed");});

//if you want uncomment below to show leaderboard!
//Social.ShowLeaderboardUI();
    }
    else
        Debug.Log ("Failed to authenticate");
        
 #endif
}



Generating "Always On Top" NSWindow in macOS across all detected displays

Also: Using UIKit & Cocoa Frameworks using Objective-C In m acOS or OS X , written in either Objective-C or Swift  Langues, you m...