Thursday, July 15, 2021

unity 3rd person camera

 https://code.tutsplus.com/tutorials/unity3d-third-person-cameras--mobile-11230

Monday, July 12, 2021

get content logfile by power shell

 In any batchmode run you can specify a log file location with an argument -logFile, this file will be written into live during the execution of the given method. You can easily monitor the file using different commands. One of them is from powershell: get-content "c:\location-to-your-log.log" -wait


unity-realtime-log command line

 https://github.com/mr-kelly/unity_realtime_log

Thursday, July 8, 2021

Document A* and reference implementation

explain

https://learn.unity.com/tutorial/graph-theory#5e0b72d3edbc2a144cf5cb47

Early exit

https://www.redblobgames.com/pathfinding/early-exit/

Region growth or procedural map

https://www.redblobgames.com/pathfinding/distance-to-any/#region-growth

Apply to towerdefense

https://www.redblobgames.com/pathfinding/tower-defense/

Movement cost and Infulence map for detect enemy or friendly unit

http://theory.stanford.edu/~amitp/GameProgramming/MovementCosts.html


 http://theory.stanford.edu/~amitp/GameProgramming/ImplementationNotes.html

I go into a lot more detail here, with interactive diagrams.

⁽¹⁾ I’m skipping a small detail here. You do need to check to see if the node’s g value can be lowered, and if so, you re-open it.

OPEN = priority queue containing START
CLOSED = empty set
while lowest rank in OPEN is not the GOAL:
  current = remove lowest rank item from OPEN
  add current to CLOSED
  for neighbors of current:
    cost = g(current) + movementcost(current, neighbor)
    if neighbor in OPEN and cost less than g(neighbor):
      remove neighbor from OPEN, because new path is better
    if neighbor in CLOSED and cost less than g(neighbor): ⁽²⁾
      remove neighbor from CLOSED
    if neighbor not in OPEN and neighbor not in CLOSED:
      set g(neighbor) to cost
      add neighbor to OPEN
      set priority queue rank to g(neighbor) + h(neighbor)
      set neighbor's parent to current

reconstruct reverse path from goal to start
by following parent pointers

https://pavcreations.com/pathfinding-with-a-star-algorithm-in-unity-small-game-project/

We now have all the elements to start writing the main algorithm. Let’s get right to it!OPEN_LIST
CLOSED_LIST
ADD start_cell to OPEN_LIST

LOOP
    current_cell = cell in OPEN_LIST with the lowest F_COST
    REMOVE current_cell from OPEN_LIST
    ADD current_cell to CLOSED_LIST

IF current_cell is finish_cell
    RETURN

FOR EACH adjacent_cell to current_cell
    IF adjacent_cell is unwalkable OR adjacent_cell is in CLOSED_LIST
        SKIP to the next adjacent_cell

    IF new_path to adjacent_cell is shorter OR adjacent_cell is not in OPEN_LIST
        SET F_COST of adjacent_cell
        SET parent of adjacent_cell to current_cell
        IF adjacent_cell is not in OPEN_LIST
            ADD adjacent_cell to OPEN_LIST

Wednesday, July 7, 2021

ToString("N1", new CultureInfo("vi-VN"));

 https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings

Wednesday, June 30, 2021

Attribute execute button on editor mode

 #region namespace

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEditor;
#endregion
public class CuonglhButton : MonoBehaviour
{
    [ButtonEditor]
    public void TestButton()
    {
        Debug.Log("Execute");
    }
}

[AttributeUsage(AttributeTargets.Method)]
public class ButtonEditor : Attribute { }

[CustomEditor(typeof(MonoBehaviour), true)]
public class CuonglhButtonEditor : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        var mTarget = (MonoBehaviour) target;
        var methodInfors = mTarget.GetType().GetMethods();
        foreach (var methodInfor in methodInfors)
        {
            var buttonEditor = methodInfor.GetCustomAttribute(typeof(ButtonEditor), true);
            if (buttonEditor != null)
            {
                if (GUILayout.Button(methodInfor.Name))
                {
                    methodInfor.Invoke((object)mTarget, null);
                }
            }
        }
    }
}