unity常用参数及技巧

点击判断(2d sprite)

if (Input.GetMouseButton(0))
{


    //从摄像机发出射线的点
    Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    Vector2 MousePos2D = new Vector2(mousePos.x, mousePos.y);

    RaycastHit2D hit = Physics2D.Raycast(MousePos2D, Vector2.zero);


    if (hit.collider!=null)
    {
        print("成功点击");
    }
}

获取鼠标位置

Input.mousePosition
Camera.main.ScreenToWorldPoint(Input.mousePosition);
mouseWorldPosition.z = 0f;

根据鼠标位置放置prefab

if (Input.GetMouseButtonDown(0))
{
    Instantiate(pfwoodHarvester, GetMouseWorldPosition(), Quaternion.identity);
}

建立scriptobject

[CreateAssetMenu(menuName ="ScriptableObjects/BuildingType")]
public class BuildingTypeSO : ScriptableObject
{
    public string nameString;
    public Transform prefab;
}

用resource来导入不同的scriptobject,可以嵌套已经做好了的scriptableobject

[CreateAssetMenu(menuName = "ScriptableObjects/BuildingTypeList")]
public class BuildingTypeListSO : ScriptableObject
{
    public List<BuildingTypeSO> list;

}

在这里插入图片描述

buildingTypeList=Resources.Load<BuildingTypeListSO>(typeof(BuildingTypeListSO).Name);
buildingType = buildingTypeList.list[0];

计时器

每过一秒做一次

private float timer;
private float timerMax;

private void Awake()
{
    timerMax = 1f;
}

private void Update()
{
    timer -= Time.deltaTime;
    if (timer <= 0f)
    {
        timer += timerMax;
        Debug.Log("Ding");
    }
}

显示自定义数据结构

[System.Serializable]
public class ResourceGeneratorData 
{
    public float timerMax;
    public ResourceTypeSO resourceType;
}

单例模式

因为prefab可以在任何场景被建立,因此它可以取到的内容必须是一个asset,而不是场景内物件。为此,我们可以用到单例模式
比如一个资源物件,出现后会让当前全局的一个脚步数值增加数量,这个脚本就最好为单例。

public static ResourceManager Instance
{
    get;
    private set;
}
private void Awake()
{
    Instance = this;
}

prefab中可以这样获取这个脚本:

ResourceManager.Instance.AddResource(buildingType.resourceGeneratorData.resourceType, 1);

不用prefab,直接用一个transform来做UI的模板

这个方法很好,在你有资源添加进去后,它会自动增加。

		Transform resourceTemplate = transform.Find("ResourcesTemplate");
		resourceTemplate.gameObject.SetActive(false);//把模板设置为看不见
        int index = 0;
        foreach (ResourceTypeSO resourceType in resourceTypeList.list)
        {
            Transform resourceTransform = Instantiate(resourceTemplate, transform);//生成一个自己。
            resourceTransform.gameObject.SetActive(true);

            float offsetAmount = -160f;
            resourceTransform.GetComponent<RectTransform>().anchoredPosition = new Vector2(offsetAmount*index,0);
            
			//找到模板物件下方的子物体进行更改
            resourceTransform.Find("Image").GetComponent<Image>().sprite = resourceType.sprite;


            resouceTypeTransformDictionary[resourceType] = resourceTransform;
            index++;

        }

结构如下

TextMeshPro如何找到自己的脚本

resouceTransform.Find("Text").GetComponent<TMP_Text>().SetText(resourceAmount.ToString());

Event

发布者不需要直到它要干嘛只需要直到它在什么时候要做什么。
其他人可以往这个时机里添加内容。

public event EventHandler OnResourceAmountChanged;

在某时机要做什么

OnResourceAmountChanged?.Invoke(this,EventArgs.Empty);

其他人需要填充内容,表示它在这个时机是要做什么

    ResourceManager.Instance.OnResourceAmountChanged += ResourceManager_OnResourceAmountChanged;
    UpdateResourceAmount();
}

private void ResourceManager_OnResourceAmountChanged(object sender, System.EventArgs e)
{
    UpdateResourceAmount();
}

比如,在healthsystem中设置event。它规定了何时触发
在这里插入图片描述
在building中进行注册,当死亡时需要对它有所效果
在这里插入图片描述
在血量条中对它进行注册,当损血时,它会有所变化
在这里插入图片描述

自定义参数的event

调用者

private void Start()
{
    BuildingManager.Instance.OnActiveBuildingTypeChanged += BuildingMnager_OnActiveBuildingTypeChanged;
    
}
private void BuildingMnager_OnActiveBuildingTypeChanged(object sender, BuildingManager.OnActiveBuildingTypeChangedEventArgs e)
{
    UpdateActiveBuildingTypeButton();
}

建立event

public event EventHandler<OnActiveBuildingTypeChangedEventArgs> OnActiveBuildingTypeChanged;

public class OnActiveBuildingTypeChangedEventArgs : EventArgs
OnActiveBuildingTypeChanged?.Invoke(this,new OnActiveBuildingTypeChangedEventArgs { activeBuildingType=activeBuildingType});

2D模式下的渲染顺序

从上到下
在这里插入图片描述
也是从小到大
都是从小到大。

相机移动

用cinemachine设置跟随target,在target中挂脚本写上:

private void Update()
{
    float x = Input.GetAxisRaw("Horizontal");
    float y = Input.GetAxisRaw("Vertical");

    Vector2 moveDir=new Vector2(x, y).normalized;
    float moveSped = 5f;

    transform.position += (Vector3)moveDir * moveSped * Time.deltaTime;
}

缩小场景视野大小。
也是用cinemachine

获得cinemachine

[SerializeField] private CinemachineVirtualCamera cinemachineVirtualCamera;

 private void Start()
{
    orthographicSize = cinemachineVirtualCamera.m_Lens.OrthographicSize;
}

private void Update()
{

    float zoomAmount = 2f;
    orthographicSize += Input.mouseScrollDelta.y * zoomAmount;

    float minorthographicSize = 10;
    float maxorthographicSize = 30;
    orthographicSize = Mathf.Clamp(orthographicSize,minorthographicSize, maxorthographicSize);


    cinemachineVirtualCamera.m_Lens.OrthographicSize = orthographicSize;
}

在移动时增加减速效果

targetorthographicSize = Mathf.Clamp(targetorthographicSize, minorthographicSize, maxorthographicSize);
float zoomSped = 30f;
orthographicSize = Mathf.Lerp(orthographicSize, targetorthographicSize, zoomSped * Time.deltaTime);
cinemachineVirtualCamera.m_Lens.OrthographicSize = orthographicSize;

用函数EventSystem.current.IsPointerOverGameObject()来解决ui点击层级问题

if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject())
{
    Instantiate(buildingType.prefab, GetMouseWorldPosition(), Quaternion.identity);
}

动态增加按钮监听函数

        btnTransform.GetComponent<Button>().onClick.AddListener(() =>{
            BuildingManager.Instance.SetActiveBuildingType(buildingType);
        } );

缩小图片大小

arrowBtn.Find("image").GetComponent<Image>().sprite = arrowSprite;
arrowBtn.Find("image").GetComponent<RectTransform>().sizeDelta = new Vector2(0, -40);

2D-Y轴顺序

挂在物件prefab上。

public class SpritePositionSortingOrder : MonoBehaviour {

    [SerializeField] private bool runOnce;
    [SerializeField] private float positionOffsetY;

    private SpriteRenderer spriteRenderer;

    private void Awake() {
        spriteRenderer = GetComponent<SpriteRenderer>();
    }

    private void LateUpdate() {
        float precisionMultiplier = 5f;
        spriteRenderer.sortingOrder = (int) (-(transform.position.y + positionOffsetY) * precisionMultiplier);

        if (runOnce) {
            Destroy(this);
        }
    }
}

让update暂停运作

if (nearbyResourceAmount == 0)
{
    // No resource nodes nearby
    // Disable resource generator
    enabled = false;
}

用物理引擎找到周边的物体

Collider2D[] collider2DArray = Physics2D.OverlapCircleAll(transform.position, resourceGeneratorData.resourceDetectionRadius);

        int nearbyResourceAmount = 0;
        foreach (Collider2D collider2D in collider2DArray)
        {
            ResourceNode resourceNode = collider2D.GetComponent<ResourceNode>();
            if (resourceNode != null)
            {
                // It's a resource node!
                if (resourceNode.resourceType == resourceGeneratorData.resourceType)
                {
                    // Same type!
                    nearbyResourceAmount++;
                }
            }
        }

根据资源的数量,减少增加资源的冷却时间

    timerMax = (resourceGeneratorData.timerMax / 2f) +
        resourceGeneratorData.timerMax *
        (1 - (float)nearbyResourceAmount / resourceGeneratorData.maxResourceAmount);

获取canvas的位置,按照 screen size的canvas

在这里插入图片描述

鼠标触发事件

在这里插入图片描述

简易朝着目标移动

在这里插入图片描述

检测碰撞

在这里插入图片描述

指向那个位置的小箭头

在这里插入图片描述
指向对象在屏幕内,消失
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值