【持续更新】Unity代码片段积累

1. 解决Texture2D提示压缩格式问题,无法转byte[]

public static Texture2D DeCompress(Texture2D source)
{
    RenderTexture renderTex = RenderTexture.GetTemporary(
        source.width,
        source.height,
        0,
        RenderTextureFormat.Default,
        RenderTextureReadWrite.Linear);

    Graphics.Blit(source, renderTex);
    RenderTexture previous = RenderTexture.active;
    RenderTexture.active = renderTex;

    Texture2D readableText = new Texture2D(source.width, source.height);
    readableText.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
    readableText.Apply();

    RenderTexture.active = previous;
    RenderTexture.ReleaseTemporary(renderTex);

    return readableText;
}

2. Texture2D尺寸压缩

/**
 * Reference: https://gamedev.stackexchange.com/questions/92285/unity3d-resize-texture-without-corruption
 */
public static Texture2D ResizeTexture(Texture2D source, int newWidth, int newHeight)
{
    FilterMode mode = FilterMode.Bilinear;
    source.filterMode = mode;

    RenderTexture lastRt = RenderTexture.active;
    RenderTexture rt = RenderTexture.GetTemporary(newWidth, newHeight);
    rt.filterMode = mode;
    RenderTexture.active = rt;
    Graphics.Blit(source, rt);

    Texture2D nTex = new Texture2D(newWidth, newHeight);
    nTex.ReadPixels(new Rect(0, 0, newWidth, newHeight), 0, 0);
    nTex.Apply();
    RenderTexture.active = lastRt;
    RenderTexture.ReleaseTemporary(rt);

    return nTex;
}

/**
 * Attention: Not supported on DX9 or Mac+OpenGL
 */
public static Texture2D ConvertTexture(Texture2D orgText, int width, int height)
{
    Texture2D newTex = new Texture2D(width, height);
    Graphics.ConvertTexture(orgText, newTex);
    return newTex;
}
# 3. Texture2D裁剪 ```C# /** * The cut width and height should be less than the size of the source texture size. */ public static Texture2D CutTexture(Texture2D source, int cutWidth, int cutHeight, int cutOffX = 0, int cutOffY = 0) { FilterMode mode = FilterMode.Bilinear; source.filterMode = mode; RenderTexture lastRt = RenderTexture.active; RenderTexture rt = RenderTexture.GetTemporary(source.width, source.height); rt.filterMode = mode; RenderTexture.active = rt; Graphics.Blit(source, rt); Texture2D nTex = new Texture2D(cutWidth, cutHeight); int deltaX = source.width - cutWidth; int deltaY = source.height - cutHeight; int paddingX = Mathf.Max((int)(deltaX * 0.5f) + cutOffX, 0); paddingX = Mathf.Min(paddingX, deltaX); int paddingY = Mathf.Max((int)(deltaY * 0.5f) + cutOffY, 0); paddingY = Mathf.Min(paddingY, deltaY); nTex.ReadPixels(new Rect(paddingX, paddingY, cutWidth, cutHeight), 0, 0); nTex.Apply(); RenderTexture.active = lastRt; RenderTexture.ReleaseTemporary(rt); return nTex; }

4. Texture2D 90度旋转

public static Texture2D RotateTexture(Texture2D orgTex, bool rotLeft)
{
    FilterMode mode = FilterMode.Bilinear;
    orgTex.filterMode = mode;

    RenderTexture lastRt = RenderTexture.active;
    RenderTexture rt = RenderTexture.GetTemporary(orgTex.width, orgTex.height);
    rt.filterMode = mode;
    RenderTexture.active = rt;
    Graphics.Blit(orgTex, rt);

    Texture2D newTex = new Texture2D(rt.width, rt.height);
    newTex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
    newTex.Apply();
    RenderTexture.active = lastRt;
    RenderTexture.ReleaseTemporary(rt);

    newTex = InnerRotateTexture(newTex, rotLeft);

    return newTex;
}

private static Texture2D InnerRotateTexture(Texture2D orgTex, bool rotLeft)
{
    int width = orgTex.width, height = orgTex.height;
    Color32[] orgColors = orgTex.GetPixels32();

    Texture2D newTex = new Texture2D(height, width);
    Color32[] newColors = newTex.GetPixels32();

    for (int i = 0; i < width - 1; i++)
    {
        for (int j = 0; j < height - 1; j++)
        {
            int x = rotLeft ? height - 1 - j : j, y = rotLeft ? i : width - 1 - i;
            newColors[y * height + x] = orgColors[j * width + i];
        }
    }

    newTex.SetPixels32(newColors);
    newTex.Apply();
    return newTex;
}

public static Texture2D RotateFlipTexture(Texture2D orgTex, bool isFlip = false)
{
    int width = orgTex.width, height = orgTex.height;
    Color32[] orgColors = orgTex.GetPixels32();

    Texture2D newTex = new Texture2D(height, width);
    Color32[] newColors = newTex.GetPixels32();

    for (int i = 0; i < width - 1; i++)
    {
        for (int j = 0; j < height - 1; j++)
        {
            int x = isFlip ? height - 1 - j : j, y = isFlip ? i : width - 1 - i;
            if (isFlip) x = height - x;
            newColors[y * height + x] = orgColors[j * width + i];
        }
    }

    newTex.SetPixels32(newColors);
    newTex.Apply();
    return newTex;
}

5. 调用Android代码

/**
 * "com.unity3d.player.UnityPlayerActivity"为需要调用的方法所在类的路径(包名+类名);
 * "mInstance"为对应类记录的实例变量,根据变量是否是static,可调用 GetStatic 或 Get;
 */
public static AndroidJavaObject GetCurActivity()
{
    AndroidJavaClass javaCls = new AndroidJavaClass("com.unity3d.player.UnityPlayerActivity");
    AndroidJavaObject curActivity = javaCls.GetStatic("mInstance");
    return curActivity;
}

/**
 * "funcName"为需要调用的方法名称;
 * param为方法需要传入的参数;
 * 根据方法是否为static,可调用 CallStatic 或 Call;
 */
public static T CallFunc(Object param)
{
    AndroidJavaObject activity = GetCurActivity();
    if (activity != null)
    {
        return activity.Call("funcName", param);
    }
}

6. 单例基类的实现

using UnityEngine;

public class Singleton : MonoBehaviour where T : Singleton
{
    private static T instance;

    public static T Instance
    {
        get { return instance; }
    }

    public static bool IsInitialized
    {
        get { return instance != null; }
    }

    protected virtual void Awake()
    {
        if (instance != null)
            Destroy(gameObject);
        else
            instance = (T)this;
    }

    protected virtual void OnDestroy()
    {
        if (instance == this)
        {
            instance = null;
        }
    }
}

子类的代码实现:

public class ApiManager : Singleton
{
    // ...
}

7. PaveView的实现代码

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class PageView : MonoBehaviour, IBeginDragHandler, IEndDragHandler
{
    public Action OnPageChanged;
    public RectTransform tfContent;

    public float smoothing = 4;
    public float sensitivity = 0;

    ScrollRect rect;

    bool isDrag = false;
    bool isStopMove = true;

    int curPageIndex = -1;
    float targetHorizontal = 0;
    float startDragHorizontal;
    float startTime = 0;

    List posList = new List();

    private void Awake()
    {
        rect = GetComponent();
    }

    private void Update()
    {
        if (!isDrag && !isStopMove)
        {
            startTime += Time.deltaTime;

            float t = startTime * smoothing;
            rect.horizontalNormalizedPosition = Mathf.Lerp(rect.horizontalNormalizedPosition, targetHorizontal, t);
            if (t > 1) isStopMove = true;
        }
    }

    public void PageTo(int index)
    {
        if (index >= 0 && index < posList.Count)
        {
            rect.horizontalNormalizedPosition = posList[index];
            SetPageIndex(index);
            GetIndex(index);
        }
    }

    private void SetPageIndex(int index)
    {
        if (curPageIndex == index) return;

        curPageIndex = index;
        if (OnPageChanged != null) OnPageChanged(index);
    }

    private void GetIndex(int index)
    {

    }

    public void AddItem(RectTransform child)
    {
        child.SetParent(tfContent);
        child.localScale = Vector3.one;
    }

    public void Activate()
    {
        int count = tfContent.transform.childCount;
        var itemW = GetComponent().rect.width;
        var tmpWidth = ((float)count * itemW);
        tfContent.sizeDelta = new Vector2(tmpWidth, 0);

        float widthNotShow = tfContent.rect.width - itemW;
        for (int i = 0; i < count; i++)
        {
            posList.Add(itemW * i / widthNotShow);
        }
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        isDrag = true;
        startDragHorizontal = rect.horizontalNormalizedPosition;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        float posX = rect.horizontalNormalizedPosition;
        posX += ((posX - startDragHorizontal) * sensitivity);
        posX = posX < 1 ? posX : 1;
        posX = posX > 0 ? posX : 0;

        int index = 0;
        float offset = Mathf.Abs(posList[index] - posX);

        for (int i = 1; i < posList.Count; i++)
        {
            float tmp = Mathf.Abs(posList[i] - posX);
            if (tmp < offset)
            {
                index = i;
                offset = tmp;
            }
        }

        SetPageIndex(index);
        GetIndex(index);
        targetHorizontal = posList[index];
        startTime = 0;
        isDrag = false;
        isStopMove = false;
    }
}

使用:

ScrollView + PageView;

image
image
image

8. Android代码判断权限

private static int PERMISSION_CODE = 1;
private String _unityObjName = "";
private Map permissionResults = new HashMap<>();

public boolean hasPermission(String permission)
{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
    {
        return this.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
    }
    else
    {
        return PermissionChecker.checkSelfPermission(this, permission) == PermissionChecker.PERMISSION_GRANTED;
    }
}

public void requestPermission(String permission, String objName)
{
    _unityObjName = objName;

    String[] permissions;
    if (Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission) || Manifest.permission.READ_EXTERNAL_STORAGE.equals((permission)))
    {
        permissions = new String[] {
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE
            };
    }
    else
    {
        permissions = new String[] {permission};
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
    {
        this.requestPermissions(permissions, PERMISSION_CODE);
    }
    else
    {
        ActivityCompat.requestPermissions(this, permissions, PERMISSION_CODE);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (requestCode != PERMISSION_CODE) return;

    for (int i = 0; i < permissions.length; i++)
    {
        String permission = permissions[i];
        int grantResult = grantResults[i];

        boolean granted = (grantResult == PackageManager.PERMISSION_GRANTED);
        if (granted)
        {
            sendUnityMessage("OnPermissionAccepted", permission);
        }
        else
        {
            sendUnityMessage("OnPermissionDenied", permission);
        }

        if (permissionResults.containsKey(permission))
            permissionResults.remove(permission);

        permissionResults.put(permission, granted);
    }
}

/**
     * Used for Android M bellowing
     * @param permission
     * @return
     */
public boolean isPermissionGranted(String permission)
{
    if (isAboveAndroidM()) return false;
    return permissionResults.get(permission);
}

private void sendUnityMessage(String funcName, String param)
{
    UnityPlayer.UnitySendMessage(_unityObjName, funcName, param);
}

9. Android跳转当前应用的设置详情

public void goCurrentAppSettings()
{
    Intent intent = new Intent();
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
    intent.setData(Uri.fromParts("package", getPackageName(), null));
    startActivity(intent);
}

10. Android调用Unity的C#代码

UnityPlayer.UnitySendMessage(scriptName, funcName, stringParam);

你可能感兴趣的:(【持续更新】Unity代码片段积累)