前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【持续更新】Unity代码片段积累

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

作者头像
代码咖啡
发布2022-01-09 09:11:20
5020
发布2022-01-09 09:11:20
举报
文章被收录于专栏:程序员叨叨叨

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

代码语言:javascript
复制
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尺寸压缩

代码语言:javascript
复制
/**
 * 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;
}</pre>

# 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度旋转

代码语言:javascript
复制
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;
}

代码语言:javascript
复制
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代码

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

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

6. 单例基类的实现

代码语言:javascript
复制
using UnityEngine;

public class Singleton<T> : MonoBehaviour where T : Singleton<T>
{
    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;
        }
    }
}

子类的代码实现:

代码语言:javascript
复制
public class ApiManager : Singleton<ApiManager>
{
    // ...
}

7. PaveView的实现代码

代码语言:javascript
复制
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<int> 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<float> posList = new List<float>();

    private void Awake()
    {
        rect = GetComponent<ScrollRect>();
    }

    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<RectTransform>().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代码判断权限

代码语言:javascript
复制
private static int PERMISSION_CODE = 1;
private String _unityObjName = "";
private Map<String, Boolean> 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跳转当前应用的设置详情

代码语言:javascript
复制
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#代码

代码语言:javascript
复制
UnityPlayer.UnitySendMessage(scriptName, funcName, stringParam);
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021.09.15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 解决Texture2D提示压缩格式问题,无法转byte[]
  • 2. Texture2D尺寸压缩
  • 4. Texture2D 90度旋转
  • 5. 调用Android代码
  • 6. 单例基类的实现
  • 7. PaveView的实现代码
  • 8. Android代码判断权限
  • 9. Android跳转当前应用的设置详情
  • 10. Android调用Unity的C#代码
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档