Wednesday, July 29, 2020

Photon engine learning

MonoBehaviourPunCallbacks: room connect join callback PUN or Register callback from PhotonNetwork.AddCallbackTarget()

MonoBehaviourPun: photonview

IPunObservable : OnPhotonSerializeView

Tuesday, July 28, 2020

Asa’s tips for shader profiling and optimization

https://unity3d.com/how-to/shader-profiling-and-optimization-tips

To calculate camera view World Position vs gameobject world position check out of boundary view

https://docs.unity3d.com/Manual/FrustumSizeAtDistance.html

The Size of the Frustum at a Given Distance from the Camera

A cross-section of the view frustum at a certain distance from the camera defines a rectangle in world space that frames the visible area. It is sometimes useful to calculate the size of this rectangle at a given distance, or find the distance where the rectangle is a given size. For example, if a moving camera needs to keep an object (such as the player) completely in shot at all times then it must not get so close that part of that object is cut off.

The height of the frustum at a given distance (both in world units) can be obtained with the following formula:

 var frustumHeight = 2.0f * distance * Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad);

…and the process can be reversed to calculate the distance required to give a specified frustum height:

 var distance = frustumHeight * 0.5f / Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad);

It is also possible to calculate the FOV angle when the height and distance are known:

 var camera.fieldOfView = 2.0f * Mathf.Atan(frustumHeight * 0.5f / distance) * Mathf.Rad2Deg;

Each of these calculations involves the height of the frustum but this can be obtained from the width (and vice versa) very easily:

var frustumWidth = frustumHeight * camera.aspect;
var frustumHeight = frustumWidth / camera.aspect;

Sunday, July 26, 2020

OnPhotonSerializeView what is it RPC, RaiseEvent

RaiseEvent vs RPC in PhotonEngine

https://forum.unity.com/threads/rpcs-vs-raiseevents.573007/

Generally speaking the easiest way to instantiate networked objects is by using PhotonNetwork.Instantiate, or PhotonNetwork.InstantiateSceneObject.

You can use RPCs or RaiseEvent to achieve the same, but then you need to manually do a lot of stuff that is automatically taken care of for you by PhotonNetwork.Instantiate, such as allocating viewIDs and cleaning up when a player disconnects.

The only advantage of RPCs over RaisEvent, in my opinion, is simplicity as there is less work required to get them working, but the con is that they require objects to have a PhotonView attached.

RaiseEvent on the other hand is much more flexible in as much as no PhotonViews are required and you decide which scripts will listen for and respond to them. You also have greater control over which clients you send to, which can save bandwidth.

I don't use RPCs at all now, preferring RaiseEvent for everything.

This is just fairly general personal opinion on my part, if you require more specific help you should post some of your code with a description of what you want it to do vs what it is actually doing.

Friday, July 24, 2020

SingletonMonoBehaviour

using UnityEngine;
using System.Collections;

public class SingletonMonoBehaviour<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T instance;

    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = (T)FindObjectOfType(typeof(T));

                if (instance == null)
                {
                    //  Debug.LogError (typeof(T) + "is nothing");
                    GameObject singleton = new GameObject();
                    instance = singleton.AddComponent<T>();
                    singleton.name = typeof(T).ToString();
                }
            }

            return instance;
        }
    }

    public virtual void Awake()
    {
        CheckInstance();
    }

    protected bool CheckInstance()
    {
        if (this == Instance) { return true; }
        Destroy(this);
        return false;
    }
}

Calculate orthorgraphic camera size for tilemap based 2dGame

Pixel Perfect Calculator for Orthographic Camera : Unity3D


It’s pretty easy to setup an Orthographic Camera in Unity, but without paying attention the settings can cause us numerous problems when it comes to sprites, textures and the quest for pixel perfect graphics in our games.
When wanting pixel perfect graphics it is important that we set the camera size to give us a 1:1 pixel/texture ration between Photoshop (or your alternative) and Unity.
For example, if our game resolution is set to width = 960px height = 640px and our camera size is set to 5 a Unity cube (scaled at 1,1,1) will be the equivalent of a 64px by 64px square in Photoshop. This means that our game screen will have space for ten 64px sprites stacked on top of each other.
Camera Size Explaination
Many game devs will prefer to work with a set size in Photoshop and then adjust their camera setup in Unity accordingly. Depending on the resolution and the target Photoshop size this can require some complicated trial and error. However an untraceable contributor  in the comments section of Rocket 5’s wonderful tutorial series on 2D in Unity , provided a formula thus avoiding the trial and error.
Camera Size = x / ((( x / y ) * 2 ) * s )
Where:
x = Screen Width (px)
y = Screen Height (px)
s = Desired Height of Photoshop Square (px)
It’s a formula that works perfectly and I have setup a calculator to make the calculation process even easier via my Pixel Perfect Camera Size Calculator – Google Doc. Feel free to share, use and download as you wish.
Pixel Perfect Calculator
Pixel Perfect Calculator

Tuesday, July 21, 2020

Delegate vs Event C#

http://www.unitygeek.com/delegates-events-unity/

Objective:

The Objective of the tutorial is to understand how to use and implement Delegates and Events in Unity.
If you enjoyed my previous tutorial about Singletonthis is second of many tutorials to learn how to use unity to full potential and write efficient code in Unity.

Introduction :

Delegates and Events is very powerful feature of C# programming language, it helps to write efficient and clean code in unity.

Delegate :

A Delegate is a reference pointer to a method. It allows us to treat method as a variable and pass method as a variable for a callback. When it get called , it notifies all methods that reference the delegate. The basic idea behind them is exactly the same as a subscription magazine. Anyone can subscribe to the service and they will receive the update at the right time automatically.
I know at this time everything seems very confusing, just wait everything will be clear when start doing coding.

Types of Delegate:

  • Single Delegate :
    It can reference to only single method at a time.
  • Multicast Delegate :
    It can store the reference of multiple methods at a time.

Syntax :

?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
//Defining Delegate
public delegate void OnButtonClickDelegate();
public static OnButtonClickDelegate buttonClickDelegate;
 
//Subscribing to delegate
 
// eg. of Singlecast
buttonClickDelegate = myCustomMethod;
 
//eg. of Multicast Delegate
buttonClickDelegate += myCustomMethod;
buttonClickDelegate +=myAnotherCustomMethod
 
//Calling Delegates
buttonClickDelegate();
 
//UnSubscribing to Delegate
buttonClickDelegate -= myCustomMethod;
buttonClickDelegate -=myAnotherCustomMethod
let see this in action, Create new script named DelegateHandler and attached to empty gameobject and paste below code
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
using UnityEngine;
using System.Collections;
 
public class DelegateHandler : MonoBehaviour
{
 
     public delegate void OnButtonClickDelegate ();
     public static OnButtonClickDelegate buttonClickDelegate;
      
     public void OnButtonClick()
     {
       buttonClickDelegate ();
     }
 
}
and now create a sphere from GameObject>3D Object >Sphere and create new script named ObjectController and attached to the sphere and add below code to ObjectController class
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using UnityEngine;
using System.Collections;
 
public class ObjectController : MonoBehaviour {
 
    Renderer objRenderer;
    // Use this for initialization
    void Start ()
    {
      DelegateHandler.buttonClickDelegate += ChangePosition;
      DelegateHandler.buttonClickDelegate += ChangeColor;
      objRenderer = GetComponent<Renderer>();
    }
 
    void ChangePosition()
    {
      transform.position = new Vector2 (transform.position.x + 2f, transform.position.y);
    }
 
    void ChangeColor()
    {
      objRenderer.material.color = Color.yellow;
    }
 
    // Unsubscribing Delegate
    void OnDisable()
    {
      DelegateHandler.buttonClickDelegate -= ChangeColor;
      DelegateHandler.buttonClickDelegate -= ChangePosition;
    }
 
 }

now in the inspector attach button event to the DelegateHandler  “OnButtonClick” method and click play. You will see it will call are assigned method if we click on the button. In this manner, any class can subscribe to OnButtonClickDelegate and get a callback, when this gets called.I hope it make some sense now.
But this implementation prone to error, as we discussed earlier there are two types of delegates, so if we use singlecast delegate options after multicast delegate, it will reset the existing invocation method list.
Now create a new method ChangeRotation and change the start method of  ObjectController Class as below.
?
1
2
3
4
5
6
7
void Start ()
{
  DelegateHandler.buttonClickDelegate += ChangePosition;
  DelegateHandler.buttonClickDelegate += ChangeColor;
  Delegatehandler.buttonClickDelegate = ChangeRotation;
  objRenderer = GetComponent ();
}
and run the unity, you will notice now ChangePosition and ChangeColor will not get called,only ChangeRotation code will run, this is because, assign operator will reset the existing invocation list, this situation is very difficult to track if multiple classes subscribe to same delegate, to avoid this situation, we use Events.

Events :

Events adds a layer of abstraction and protection on delegate, this protection prevents client of the delegate from resetting the delegate and invocation list. Events only allow to add and remove method from invocation list.
Change the DelegateHandler class as below
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
using UnityEngine;
using System.Collections;
 
public class DelegateHandler : MonoBehaviour
{
 
     public delegate void OnButtonClickDelegate ();
     public static event OnButtonClickDelegate buttonClickDelegate;
      
     public void OnButtonClick()
     {
       buttonClickDelegate ();
     }
 
}
now if you go to unity, it will show error message “The event `DelegateHandler.buttonClickDelegate’ can only appear on the left hand side of += or -= when used outside of the type `DelegateHandler”.
just change the start method as below to remove the errordon’t forget to unsubscribe in OnDisable method, otherwise, it will leak memory.
?
1
2
3
//
Delegatehandler.buttonClickDelegate += ChangeRotation;
//
I hope now you have the better understanding of Delegate and Events.

Conclusion :

  • Delegates and Events help us to write modular and reusable code.
  • Always use Events together with Delegates for safety.
  • Do not forget to unsubscribe otherwise, it will lead to memory leak.