【unity实战】在 Unity 中实现卡牌翻转或者翻书的效果

最终效果

在这里插入图片描述

前言

注意,我这里只是作为参考,觉得使用shader会比较简单,其实实现方法还有很多,比如:

  • 我们可以将背面和正面设置成不同的排序层,卡牌旋转到90度时,替换这两个排序
  • 我们也可以在卡牌旋转到90度时,直接替换卡牌图片内容,替换成正面卡牌图片
  • 等等

实战

1、素材

https://assetstore.unity.com/packages/2d/gui/card-shirts-lite-165698
在这里插入图片描述

2、这里准备正面和背面两张卡牌

在这里插入图片描述
将他们作为Card的子集,叠加显示
在这里插入图片描述

3、书写shader

实现背面卡牌不渲染正面,正面卡牌不渲染背面

Shader "Unlit/one-side"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        [Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull", Float)=0
    }
    SubShader
    {
        Tags {"Queue"="Transparent" "RenderType"="Transparent"}
        Lighting Off ZWrite Off
        Cull [_Cull]

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                return col;
            }
            ENDCG
        }
    }
}

3、新增两个不渲染正面和不渲染背面的材质

在这里插入图片描述
在这里插入图片描述

4、挂载材质

在这里插入图片描述

在这里插入图片描述
现在我们只需要通过修改Card绕Y轴从0-180度旋转,就可以实现卡牌翻转的效果了
在这里插入图片描述

5、翻转卡牌

书写代码控制

using System.Collections;
using UnityEngine;

public class CardGO : MonoBehaviour
{
    // 表示卡牌是否翻转
    private bool flipped = false;
    private bool isRotating = false; // 防止旋转过程中重复触发

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) && !isRotating)
        {
            // 如果按下空格键,调用 Flip 方法翻转卡牌 
            Flip();
        }
    }

    // 翻转卡牌
    private void Flip()
    {
        flipped = !flipped;

        StartCoroutine(RotateCard(flipped ? 180f : 0f, 0.25f));
    }

    // 协程:平滑旋转卡牌
    private IEnumerator RotateCard(float targetYAngle, float duration)
    {
        isRotating = true;
        Quaternion startRotation = transform.rotation;
        // 确保角度在 [0, 360) 范围内
        targetYAngle = Mathf.Repeat(targetYAngle, 360f);
        Quaternion targetRotation = Quaternion.Euler(0, targetYAngle, 0);
        float elapsedTime = 0f;

        while (elapsedTime < duration)
        {
            // 使用 Lerp 插值计算当前旋转角度
            transform.rotation = Quaternion.Lerp(startRotation, targetRotation, elapsedTime / duration);
            elapsedTime += Time.deltaTime;
            yield return null; // 等待下一帧
        }

        // 确保最终旋转角度准确
        transform.rotation = targetRotation;
        isRotating = false;
    }
}

也可以直接使用DoTween简单的实现该效果,DoTween的使用介绍具体可以参考:【推荐100个unity插件之2】 DoTween动画插件的安装和使用整合(最全)

// 私有方法 Flip,用于翻转卡牌
private void Flip()
{
    // 切换 flipped 的值(true 变 false,false 变 true)
    flipped = !flipped;

    // 使用 DoRotate 方法在 0.25 秒内旋转卡牌
    // 如果 flipped 为 true,绕 Y 轴旋转 180 度(背面朝上)
    // 如果 flipped 为 false,绕 Y 轴旋转 0 度(正面朝上)
    transform.DoRotate(new Vector3(0, flipped ? 180f : 0, 0), 0.25f);
}

挂载脚本
在这里插入图片描述

6、效果

在这里插入图片描述


专栏推荐

地址
【unity游戏开发入门到精通——C#篇】
【unity游戏开发入门到精通——unity通用篇】
【unity游戏开发入门到精通——unity3D篇】
【unity游戏开发入门到精通——unity2D篇】
【unity实战】
【制作100个Unity游戏】
【推荐100个unity插件】
【实现100个unity特效】
【unity框架/工具集开发】
【unity游戏开发——模型篇】
【unity游戏开发——InputSystem】
【unity游戏开发——Animator动画】
【unity游戏开发——UGUI】
【unity游戏开发——联网篇】
【unity游戏开发——优化篇】
【unity游戏开发——shader篇】
【unity游戏开发——编辑器扩展】
【unity游戏开发——热更新】
【unity游戏开发——网络】

完结

好了,我是向宇,博客地址:https://xiangyu.blog.csdn.net,如果学习过程中遇到任何问题,也欢迎你评论私信找我。

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向宇it

创作不易,感谢你的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值