Unity/Animation -- 创建Animation Clip

本文详细介绍Unity游戏引擎中的动画系统,包括AnimationClip的创建方法、AnimatorController的作用及如何为游戏对象添加动画效果等。

Unity/Animation -- 创建Animation Clip

发表于2017/5/21 1:54:10  1247人阅读

分类: unity开发

前言

在游戏开发过程中,动画是一个不可或缺的环节,没有动画变换的人物并不能带给玩家很好的代入感,而Unity作为一个强大的游戏引擎,自然包括了复杂的动画系统,即Animation System。本文参考了Unity的官方文档,并加入了一定的个人理解,希望能帮助读者更快上手使用Unity 中的Animation。

重要概念

在Unity中,想要为一个游戏物体(GameObject)添加动画效果,我们可以直接为它添加Animator组件(注意,此处是Animator而非Animation)。而在每个Animator组件中我们都会调用一个Animator Controller(动画控制器),每个Animator Controller又会引用多个Animation Clip

上面一段话中的黑体字基本包含了unity动画系统中三个比较重要的概念。下面我会自下而上讲解。 
首先是最基础的Animation Clip,它可以看作是动画系统中最小的单位,游戏中角色的跑步,跳跃,攻击,摔倒都可以用一个完整的Animation Clip表示,个人把它理解为动画短片。当然了,这些动画短片我们可以自己创建,也可以导入外部的资源。最方便的当然是直接用别人的Unity Asset,但更多的时候我们是从游戏美工手上收到这些资源,不过通常是和游戏模型一起打包的,例如FBX格式的文件,可能就包含了人物模型,对应动画短片和骨架,以后有空可能会再讲,这篇博文主要聚焦在如何自己创建Animation Clip

Unity中Animation Clip的图标和属性

其次,我们还需要一个文件来部署和管理所有相关的Animation Clip,即Animator Controller,个人直译为动画控制器 
Animator Controller中定义了如何从一个一个动画状态跳转到另一个动画状态,每个动画状态对应一个动画短片。当然了,即使我们只有一个动画状态,动画控制器也是必需的,不要妄想直接把一个动画短片加到游戏物体上。举个简单的例子,我们可以根据角色的速度大小让角色在奔跑和步行两个动画状态间切换,这在unity中实现起来也比较容易,以后的博客中会详细讲解。

Unity中Animator Controller的图标和属性

当我们拥有了一个Animator Controller,我们就可以把它加到某个角色的Animator组件上控制角色的动作了,这里要注意的是Animator ControllerAnimation Clip都是文件(File),Animator则是GameObject上的一个组件(Component),不能混为一谈。

下面是Unity官方文档中给出的三者的关系: 
Animation关系图

Aniamtion关系图2

为GameObject添加动画

接下来从零开始演示如何为GameObject添加动画效果。首先在Scene中添加一个游戏物体(如Cube)

新建一个Cube

接着可以使用快捷键Ctrl + 6打开Animation的编辑窗口(这里的Animation显然是指Animation Clip),或者你也可以通过上方选项栏中的Window-Aniamtion打开。因为目前Cube上没有添加任何动画,所以我们看到的界面应该如图所示:

Animation窗口

此时回顾之前提到的,我们不能直接在GameObject上加Animation Clip,所以当该动画创建完后之后,Unity会理所当然地为我们自动创建一个Animator Controller(一般简写为Animator)。意识到这一点非常重要!!

点击Create我们就可以从零开始创建Animation了,Unity会首先要求我们选择一个保存目录(默认是在Assets目录下),这里也可以看到Animation文件是以 .anim后缀结尾。

Animation的保存

保存完成后就正式进入Animation的编辑过程了。你的Animation窗口不出意外应该如图所示。

Animation编辑界面

点击Add Property就可以添加我们想要的动画了。这里我们添加一个简单的旋转动画。

添加旋转动画

我们会发现右侧的动画进度条上多了很多东西,我们一个一个地观察它们的功能。首先是红色的竖线,代表了当前的时间,我们可以在上方的时间轴上拖动红线来改变当前动画时间。接着就是两行并行的时间线,它们完全是和左侧的属性对应的,每当我们在特定的时间点改变了属性的值,右侧的时间轴上就会对应地多出一个菱形的图标,默认情况下只有开始和结束的时间点有菱形图标。如果你觉得显示的时间轴过窄,也可以通过滑动鼠标中键缩放时间轴。默认情况下动画的跨度只有1s,可以通过改变起点和重点的菱形位置来延长和缩短动画时间。你或许还注意到所有属性轴的最上方有一个未命名的时间轴,那是记录了所有属性变化结点的总时间轴。

动画进度条

接下来要做的就是添加变换节点了,即添加小菱形。例如我们如果想在0.5s内将Cube沿y轴旋转90,再用0.5s内旋转回来,只需要添加几个关键结点即可,Animation会自动实现从0到90的平滑过渡。即有个三个重要的时间结点需要注意,0s时Cube应该未进行任何旋转,0.5s时旋转到最大值90,1s时再次沿原路旋转回0。

时间轴的含义

时间轴上的 0:30并不是说走了0.3s,而是说经过了30个采样点,看过连环画的都知道动画不过是把连续的图像高速播放罢了,三十个采样点意味着三十个连续的画面,我们可以在Animation窗口左侧的Samples中修改1s包含的采样点数,如果1s有60个采样点,经过30个时我们就可以近似认为经过了0.5s。

按照上一步分析的情况,我们应该在0:30处(采样总数为60)添加一个关键结点。第一步显然是移动红线到0:30处。这时切换到Inspector窗口,我们可以观察到Rotation属性自动红色高亮显示了。

移动红线

修改Rotation

将y值修改为90,Animation窗口的红线上就会自动多出菱形标记。到这里,我们需要的动画就制作好了,想要预览效果,可以直接点击Animation左上角选项中的播放标记。

这里写图片描述

当然,我相信你肯定不知道Unity在后台为你做了哪些工作,不了解这些工作机制,你顶多可以如法炮制,但永远不会深入理解。接下来我会加上一点个人理解,希望对你有所帮助。

Animation的编辑模式

为什么Rotation会红色高亮显示呢?这个问题可以这样回答,我们之前在Animation中添加了要被修改的属性,即Rotation。Unity接收到了我们的请求,并找到了对应的Rotation属性高亮显示,省去了我们瞎找的时间,这一点可以说是相当人性化。当然在我们移动红线的时候,Animation自动进入了编辑模式,此时被修改的值都会被纳入动画的一部分,而不是对Cube本身旋转角的修改。所以当我们终止动画时,Cube还是会采用最初的旋转角度。 
当然,我们可以手动地在编辑模式和普通模式间切换,方法非常简单,就是点击Animation窗口左上角的红色实心圆。 
1. 普通模式下进行的修改不会纳入动画中 
2. 编辑模式下的修改会全部记录在红线选定的时间点并用红色标记显示 
移动红线时,我们可以观察到红色高亮的属性会平滑变化,但未高亮的属性是绝对不会变化的

最后观察一下Cube上的组件,我们会很明显地发现新增了一个Animator,它是Unity自动为我们添加的,引用了我们创建的动画短片Animation(Clip)。

新增的Animator

再切换到Project窗口,我们可以在之前保存Aniamtion的目录下发现另外一个文件,它就是Unity为我们创建的Animator Controller,默认命名为GameObject在Scene中的名字。

新增的文件

对了,如果我们想在一个已经拥有了Animator Controller的GameObject上添加新的动画短片,可以直接在Aniamtion窗口中切换。

添加新动画

总结

用Animation系统创建动画短片的第一个Demo我们已经实现了,现在可以从头回顾一下具体的流程: 
1. 点击要添加动画的GameObject,并在Animation窗口下添加新的Aniamtion Clip 
2. Unity自动在GameObject上添加一个Animator Controller(若之前没有),并引用该Aniamtion 
3. 在编辑模式下修改具体采样点(Key)的属性,并由Unity自带的函数生成“平滑”的动画效果

后记

当然了,Animation的功能远不只这样,之前也说到了在几个极值点间属性值会“平滑”变化,这个平滑可以选择不同的函数来实现不同的效果。除了之前的关键结点视图,我们还可以切换到另一种更为复杂的曲线视图。Animator Controller可以控制GameObject在多个不同的Animation间转换。 
本人也属于初学者,很多东西还没有搞懂,感兴趣的童鞋可以自己深入了解哦~~

完整响应内容: <!DOCTYPE html><html lang="en-US" class="h-full"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, user-scalable=no"/><link rel="stylesheet" href="/_next/static/css/f6ad4df0846fb0cc.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/66adc107d4c1c96a.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/bf38d9b349c92e2b.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/20f20f233f6390b4.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/054994666d6806c5.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-c35358f6930b8983.js"/><script src="/_next/static/chunks/a70869a4-b2cf94904cef214b.js" async=""></script><script src="/_next/static/chunks/10347-2c02f7f9264c26a9.js" async=""></script><script src="/_next/static/chunks/main-app-5b430fa30793c82a.js" async=""></script><script src="/_next/static/chunks/b888e4d7-7027d2393f74ff12.js" async=""></script><script src="/_next/static/chunks/1373-f6109d301f978354.js" async=""></script><script src="/_next/static/chunks/98489-a748f271b8394120.js" async=""></script><script src="/_next/static/chunks/85855-f1b6ef0e459ffa66.js" async=""></script><script src="/_next/static/chunks/53432-9148510279b53d0a.js" async=""></script><script src="/_next/static/chunks/app/(shareLayout)/layout-e63db06d063d54da.js" async=""></script><script src="/_next/static/chunks/2c7d8ac5-811e512a50f6340f.js" async=""></script><script src="/_next/static/chunks/bda40ab4-9c001d2f3ac422cb.js" async=""></script><script src="/_next/static/chunks/fc43f782-c2a8c88db3f6459d.js" async=""></script><script src="/_next/static/chunks/75146d7d-f926a8d63b4a14a8.js" async=""></script><script src="/_next/static/chunks/476e85a8-2b79d22e950ef2ed.js" async=""></script><script src="/_next/static/chunks/adeb31b9-e830a1afda05430d.js" async=""></script><script src="/_next/static/chunks/1471f7b3-6b9ca5e0a9a9b7c0.js" async=""></script><script src="/_next/static/chunks/05417924-f0bf248afbbb93ff.js" async=""></script><script src="/_next/static/chunks/45346-bc0e6cac59b017a5.js" async=""></script><script src="/_next/static/chunks/56799-336f7bfc797cb62d.js" async=""></script><script src="/_next/static/chunks/92513-b169b60d512a03ce.js" async=""></script><script src="/_next/static/chunks/93343-147645916f0b250d.js" async=""></script><script src="/_next/static/chunks/2592-1d7026a352d1832d.js" async=""></script><script src="/_next/static/chunks/23529-d6a148ec2651082e.js" async=""></script><script src="/_next/static/chunks/96753-dfedd6dfa5f4e250.js" async=""></script><script src="/_next/static/chunks/90113-39bc72d8dd0b7155.js" async=""></script><script src="/_next/static/chunks/9293-4dba7873ac3e02a3.js" async=""></script><script src="/_next/static/chunks/7908-c0af11173f661b5e.js" async=""></script><script src="/_next/static/chunks/81877-ce227880bb766efe.js" async=""></script><script src="/_next/static/chunks/60242-6849cc56608bf2cc.js" async=""></script><script src="/_next/static/chunks/88914-7be151c3fc5a5f58.js" async=""></script><script src="/_next/static/chunks/45961-a3a5e82135280789.js" async=""></script><script src="/_next/static/chunks/9762-8b7c0a621ebcf509.js" async=""></script><script src="/_next/static/chunks/44057-c02babc825e05ce4.js" async=""></script><script src="/_next/static/chunks/12381-b8edb6ffccdddca4.js" async=""></script><script src="/_next/static/chunks/49579-57be223918cb3fc0.js" async=""></script><script src="/_next/static/chunks/7013-38579064a8eb6a11.js" async=""></script><script src="/_next/static/chunks/95019-ec8171493c6f7066.js" async=""></script><script src="/_next/static/chunks/29130-f6b5b3521461015d.js" async=""></script><script src="/_next/static/chunks/30339-0939acee317d8dbc.js" async=""></script><script src="/_next/static/chunks/24386-af3847dcffd43abc.js" async=""></script><script src="/_next/static/chunks/45140-c05b53c325e6e7ce.js" async=""></script><script src="/_next/static/chunks/55562-56e363328e9dfa14.js" async=""></script><script src="/_next/static/chunks/48736-de5ac620859df9c3.js" async=""></script><script src="/_next/static/chunks/34019-13a89f969b1debb0.js" async=""></script><script src="/_next/static/chunks/7439-40b0ce90665c76ba.js" async=""></script><script src="/_next/static/chunks/89168-cb67bf15934a2766.js" async=""></script><script src="/_next/static/chunks/24355-949a85570c42649e.js" async=""></script><script src="/_next/static/chunks/65385-330396d3a2e90a00.js" async=""></script><script src="/_next/static/chunks/60042-9a059179d0c300c2.js" async=""></script><script src="/_next/static/chunks/29289-c64de470f4edaddb.js" async=""></script><script src="/_next/static/chunks/65877-d336cb3319638ce0.js" async=""></script><script src="/_next/static/chunks/61713-33d6949b941bbd87.js" async=""></script><script src="/_next/static/chunks/87091-077c1bcf87678e20.js" async=""></script><script src="/_next/static/chunks/68137-7b2dac0e8e10cdae.js" async=""></script><script src="/_next/static/chunks/50836-762db77df23e76e8.js" async=""></script><script src="/_next/static/chunks/29401-c186b616864eb45b.js" async=""></script><script src="/_next/static/chunks/app/(shareLayout)/chat/%5Btoken%5D/page-d470b60306c5655b.js" async=""></script><script src="/_next/static/chunks/0b8e744a-7154db3c30b2ff99.js" async=""></script><script src="/_next/static/chunks/41543-60d97be99c6bd2cf.js" async=""></script><script src="/_next/static/chunks/app/layout-93943a822bace921.js" async=""></script><link rel="preload" href="/_next/static/css/220a772cfe3c95f4.css" as="style"/><link rel="preload" href="/_next/static/css/862dec1f3642e434.css" as="style"/><link rel="preload" href="/_next/static/css/1ccfd28cb5312ccf.css" as="style"/><link rel="preload" href="/_next/static/css/b8236626d75737f6.css" as="style"/><link rel="preload" href="/_next/static/css/8dd2be87966e4473.css" as="style"/><link rel="preload" href="/_next/static/css/6f20ad1915bfe966.css" as="style"/><link rel="preload" href="/_next/static/css/c31a5eb4ac1ad018.css" as="style"/><link rel="preload" href="/_next/static/css/b7247e8b4219ed3e.css" as="style"/><link rel="preload" href="/_next/static/css/91dac63556905beb.css" as="style"/><meta name="theme-color" content="#FFFFFF"/><meta name="mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-status-bar-style" content="default"/><script>document.querySelectorAll('body link[rel="icon"], body link[rel="apple-touch-icon"]').forEach(el => document.head.appendChild(el))</script><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="color-scheme h-full select-auto" data-api-prefix="/console/api" data-public-api-prefix="/api" data-marketplace-api-prefix="https://marketplace.dify.ai/api/v1" data-marketplace-url-prefix="https://marketplace.dify.ai" data-public-edition="SELF_HOSTED" data-public-sentry-dsn="" data-public-site-about="" data-public-text-generation-timeout-ms="60000" data-public-max-tools-num="10" data-public-max-parallel-limit="10" data-public-top-k-max-value="10" data-public-indexing-max-segmentation-tokens-length="4000" data-public-loop-node-max-count="100" data-public-max-iterations-num="99" data-public-max-tree-depth="" data-public-allow-unsafe-data-scheme="false" data-public-enable-website-jinareader="true" data-public-enable-website-firecrawl="true" data-public-enable-website-watercrawl="true"><div hidden=""><!--$--><!--/$--></div><script>((e,t,r,n,i,a,o,s)=>{let l=document.documentElement,u=["light","dark"];function c(t){var r;(Array.isArray(e)?e:[e]).forEach(e=>{let r="class"===e,n=r&&a?i.map(e=>a[e]||e):i;r?(l.classList.remove(...n),l.classList.add(a&&a[t]?a[t]:t)):l.setAttribute(e,t)}),r=t,s&&u.includes(r)&&(l.style.colorScheme=r)}if(n)c(n);else try{let e=localStorage.getItem(t)||r,n=o&&"system"===e?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":e;c(n)}catch(e){}})("data-theme","theme","system",null,["light","dark"],null,true,false)</script><div class="flex h-screen w-screen items-center justify-center"><div class="flex w-full items-center justify-center h-full"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="spin-animation"><g clip-path="url(#clip0_324_2488)"><path d="M15 0H10C9.44772 0 9 0.447715 9 1V6C9 6.55228 9.44772 7 10 7H15C15.5523 7 16 6.55228 16 6V1C16 0.447715 15.5523 0 15 0Z" fill="#1C64F2"></path><path opacity="0.5" d="M15 9H10C9.44772 9 9 9.44772 9 10V15C9 15.5523 9.44772 16 10 16H15C15.5523 16 16 15.5523 16 15V10C16 9.44772 15.5523 9 15 9Z" fill="#1C64F2"></path><path opacity="0.1" d="M6 9H1C0.447715 9 0 9.44772 0 10V15C0 15.5523 0.447715 16 1 16H6C6.55228 16 7 15.5523 7 15V10C7 9.44772 6.55228 9 6 9Z" fill="#1C64F2"></path><path opacity="0.2" d="M6 0H1C0.447715 0 0 0.447715 0 1V6C0 6.55228 0.447715 7 1 7H6C6.55228 7 7 6.55228 7 6V1C7 0.447715 6.55228 0 6 0Z" fill="#1C64F2"></path></g><defs><clipPath id="clip0_324_2488"><rect width="16" height="16" fill="white"></rect></clipPath></defs></svg></div></div><script src="/_next/static/chunks/webpack-c35358f6930b8983.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n3:I[22376,[\"53297\",\"static/chunks/b888e4d7-7027d2393f74ff12.js\",\"1373\",\"static/chunks/1373-f6109d301f978354.js\",\"98489\",\"static/chunks/98489-a748f271b8394120.js\",\"85855\",\"static/chunks/85855-f1b6ef0e459ffa66.js\",\"53432\",\"static/chunks/53432-9148510279b53d0a.js\",\"62090\",\"static/chunks/app/(shareLayout)/layout-e63db06d063d54da.js\"],\"default\"]\n4:I[67709,[\"53297\",\"static/chunks/b888e4d7-7027d2393f74ff12.js\",\"1373\",\"static/chunks/1373-f6109d301f978354.js\",\"98489\",\"static/chunks/98489-a748f271b8394120.js\",\"85855\",\"static/chunks/85855-f1b6ef0e459ffa66.js\",\"53432\",\"static/chunks/53432-9148510279b53d0a.js\",\"62090\",\"static/chunks/app/(shareLayout)/layout-e63db06d063d54da.js\"],\"default\"]\n5:I[71184,[],\"\"]\n6:I[96374,[],\"\"]\n7:I[89325,[],\"ClientPageRoot\"]\n"])</script><script>self.__next_f.push([1,"8:I[13801,[\"53297\",\"static/chunks/b888e4d7-7027d2393f74ff12.js\",\"65618\",\"static/chunks/2c7d8ac5-811e512a50f6340f.js\",\"18733\",\"static/chunks/bda40ab4-9c001d2f3ac422cb.js\",\"37326\",\"static/chunks/fc43f782-c2a8c88db3f6459d.js\",\"8447\",\"static/chunks/75146d7d-f926a8d63b4a14a8.js\",\"20161\",\"static/chunks/476e85a8-2b79d22e950ef2ed.js\",\"28078\",\"static/chunks/adeb31b9-e830a1afda05430d.js\",\"86640\",\"static/chunks/1471f7b3-6b9ca5e0a9a9b7c0.js\",\"25737\",\"static/chunks/05417924-f0bf248afbbb93ff.js\",\"1373\",\"static/chunks/1373-f6109d301f978354.js\",\"98489\",\"static/chunks/98489-a748f271b8394120.js\",\"85855\",\"static/chunks/85855-f1b6ef0e459ffa66.js\",\"45346\",\"static/chunks/45346-bc0e6cac59b017a5.js\",\"56799\",\"static/chunks/56799-336f7bfc797cb62d.js\",\"92513\",\"static/chunks/92513-b169b60d512a03ce.js\",\"93343\",\"static/chunks/93343-147645916f0b250d.js\",\"2592\",\"static/chunks/2592-1d7026a352d1832d.js\",\"23529\",\"static/chunks/23529-d6a148ec2651082e.js\",\"96753\",\"static/chunks/96753-dfedd6dfa5f4e250.js\",\"90113\",\"static/chunks/90113-39bc72d8dd0b7155.js\",\"9293\",\"static/chunks/9293-4dba7873ac3e02a3.js\",\"7908\",\"static/chunks/7908-c0af11173f661b5e.js\",\"81877\",\"static/chunks/81877-ce227880bb766efe.js\",\"60242\",\"static/chunks/60242-6849cc56608bf2cc.js\",\"88914\",\"static/chunks/88914-7be151c3fc5a5f58.js\",\"45961\",\"static/chunks/45961-a3a5e82135280789.js\",\"9762\",\"static/chunks/9762-8b7c0a621ebcf509.js\",\"44057\",\"static/chunks/44057-c02babc825e05ce4.js\",\"12381\",\"static/chunks/12381-b8edb6ffccdddca4.js\",\"49579\",\"static/chunks/49579-57be223918cb3fc0.js\",\"7013\",\"static/chunks/7013-38579064a8eb6a11.js\",\"95019\",\"static/chunks/95019-ec8171493c6f7066.js\",\"53432\",\"static/chunks/53432-9148510279b53d0a.js\",\"29130\",\"static/chunks/29130-f6b5b3521461015d.js\",\"30339\",\"static/chunks/30339-0939acee317d8dbc.js\",\"24386\",\"static/chunks/24386-af3847dcffd43abc.js\",\"45140\",\"static/chunks/45140-c05b53c325e6e7ce.js\",\"55562\",\"static/chunks/55562-56e363328e9dfa14.js\",\"48736\",\"static/chunks/48736-de5ac620859df9c3.js\",\"34019\",\"static/chunks/34019-13a89f969b1debb0.js\",\"7439\",\"static/chunks/7439-40b0ce90665c76ba.js\",\"89168\",\"static/chunks/89168-cb67bf15934a2766.js\",\"24355\",\"static/chunks/24355-949a85570c42649e.js\",\"65385\",\"static/chunks/65385-330396d3a2e90a00.js\",\"60042\",\"static/chunks/60042-9a059179d0c300c2.js\",\"29289\",\"static/chunks/29289-c64de470f4edaddb.js\",\"65877\",\"static/chunks/65877-d336cb3319638ce0.js\",\"61713\",\"static/chunks/61713-33d6949b941bbd87.js\",\"87091\",\"static/chunks/87091-077c1bcf87678e20.js\",\"68137\",\"static/chunks/68137-7b2dac0e8e10cdae.js\",\"50836\",\"static/chunks/50836-762db77df23e76e8.js\",\"29401\",\"static/chunks/29401-c186b616864eb45b.js\",\"90794\",\"static/chunks/app/(shareLayout)/chat/%5Btoken%5D/page-d470b60306c5655b.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"9:I[19264,[],\"OutletBoundary\"]\nc:I[30632,[],\"AsyncMetadataOutlet\"]\ne:I[19264,[],\"ViewportBoundary\"]\n10:I[19264,[],\"MetadataBoundary\"]\n12:I[559,[],\"\"]\n13:\"$Sreact.suspense\"\n14:I[30632,[],\"AsyncMetadata\"]\n16:I[81741,[\"53297\",\"static/chunks/b888e4d7-7027d2393f74ff12.js\",\"14028\",\"static/chunks/0b8e744a-7154db3c30b2ff99.js\",\"1373\",\"static/chunks/1373-f6109d301f978354.js\",\"98489\",\"static/chunks/98489-a748f271b8394120.js\",\"85855\",\"static/chunks/85855-f1b6ef0e459ffa66.js\",\"92513\",\"static/chunks/92513-b169b60d512a03ce.js\",\"41543\",\"static/chunks/41543-60d97be99c6bd2cf.js\",\"53432\",\"static/chunks/53432-9148510279b53d0a.js\",\"29130\",\"static/chunks/29130-f6b5b3521461015d.js\",\"7177\",\"static/chunks/app/layout-93943a822bace921.js\"],\"ThemeProvider\"]\n17:I[4680,[\"53297\",\"static/chunks/b888e4d7-7027d2393f74ff12.js\",\"14028\",\"static/chunks/0b8e744a-7154db3c30b2ff99.js\",\"1373\",\"static/chunks/1373-f6109d301f978354.js\",\"98489\",\"static/chunks/98489-a748f271b8394120.js\",\"85855\",\"static/chunks/85855-f1b6ef0e459ffa66.js\",\"92513\",\"static/chunks/92513-b169b60d512a03ce.js\",\"41543\",\"static/chunks/41543-60d97be99c6bd2cf.js\",\"53432\",\"static/chunks/53432-9148510279b53d0a.js\",\"29130\",\"static/chunks/29130-f6b5b3521461015d.js\",\"7177\",\"static/chunks/app/layout-93943a822bace921.js\"],\"default\"]\n18:I[54175,[\"53297\",\"static/chunks/b888e4d7-7027d2393f74ff12.js\",\"14028\",\"static/chunks/0b8e744a-7154db3c30b2ff99.js\",\"1373\",\"static/chunks/1373-f6109d301f978354.js\",\"98489\",\"static/chunks/98489-a748f271b8394120.js\",\"85855\",\"static/chunks/85855-f1b6ef0e459ffa66.js\",\"92513\",\"static/chunks/92513-b169b60d512a03ce.js\",\"41543\",\"static/chunks/41543-60d97be99c6bd2cf.js\",\"53432\",\"static/chunks/53432-9148510279b53d0a.js\",\"29130\",\"static/chunks/29130-f6b5b3521461015d.js\",\"7177\",\"static/chunks/app/layout-93943a822bace921.js\"],\"default\"]\n19:I[63146,[\"53297\",\"static/chunks/b888e4d7-7027d2393f74ff12.js\",\"14028\",\"static/chunks/0b8e744a-7154db3c30b2ff99.js\",\"1373\",\"static/chunks/1373-f6109d301f978354.js\",\"98489\",\"static/chunks/98489-a748f271b8394120.js\",\"85855\",\"static/chunks/85855"])</script><script>self.__next_f.push([1,"-f1b6ef0e459ffa66.js\",\"92513\",\"static/chunks/92513-b169b60d512a03ce.js\",\"41543\",\"static/chunks/41543-60d97be99c6bd2cf.js\",\"53432\",\"static/chunks/53432-9148510279b53d0a.js\",\"29130\",\"static/chunks/29130-f6b5b3521461015d.js\",\"7177\",\"static/chunks/app/layout-93943a822bace921.js\"],\"TanstackQueryInitializer\"]\n1b:I[60743,[\"53297\",\"static/chunks/b888e4d7-7027d2393f74ff12.js\",\"14028\",\"static/chunks/0b8e744a-7154db3c30b2ff99.js\",\"1373\",\"static/chunks/1373-f6109d301f978354.js\",\"98489\",\"static/chunks/98489-a748f271b8394120.js\",\"85855\",\"static/chunks/85855-f1b6ef0e459ffa66.js\",\"92513\",\"static/chunks/92513-b169b60d512a03ce.js\",\"41543\",\"static/chunks/41543-60d97be99c6bd2cf.js\",\"53432\",\"static/chunks/53432-9148510279b53d0a.js\",<message truncated>
最新发布
08-29
你提供的响应内容如下: ``` 完整响应内容: <!DOCTYPE html><html lang="en-US" class="h-full"><head>...(省略大量 HTML 内容)...</div></body></html> ``` --- ## ❗ 问题诊断 你收到的响应 **是一个 HTML 页面**,而不是你期望的 `text/event-stream` 类型的 JSON 流式响应。 这意味着: ### ✅ 已知信息: - ✅ API Key 有效 - ✅ 请求已发送成功 - ✅ 服务器已响应,但 **返回了网页内容(可能是登录页或错误页)** --- ## 🧠 原因分析 你收到的响应是: ```html <div class="flex h-screen w-screen items-center justify-center"> <div class="flex w-full items-center justify-center h-full"> <svg ...></svg> <!-- 一个加载动画 --> </div> </div> ``` 这说明: - ❌ 你请求的 API 地址可能 **返回了前端页面而不是 API 接口** - 🧨 可能是: 1. API 地址错误 2. 服务器未正确配置 API 路由 3. 需要登录或认证 4. 请求头配置不正确 --- ## ✅ 解决方案 ### ✅ 1. 检查 API 地址是否正确 你当前的 API 地址是: ```csharp [SerializeField] private string apiUrl = "http://localhost/chat/dNghHW0OYmuGOOd2/"; ``` 请确认: - 该地址是否是真正的 API 接口地址? - 是否应该访问类似 `/api/v1/chat-messages` 的路径? - 是否应该使用 HTTPS? - 是否应该加上 `/console/api/` 前缀? 你可以使用 **Postman 或 curl** 测试该接口是否返回流式响应。 --- ### ✅ 2. 检查请求头是否完整 你当前的请求头: ```csharp request.SetRequestHeader("Content-Type", "application/json"); request.SetRequestHeader("Authorization", $"Bearer {apiKey}"); ``` 建议你检查: - 是否需要添加 `Accept: text/event-stream`? - 是否需要添加 `X-Application-ID`、`X-User-ID` 等额外头? --- ### ✅ 3. 使用 Postman 测试接口 使用 Postman 发送如下请求: ```http POST http://localhost/chat/dNghHW0OYmuGOOd2/ Authorization: Bearer app-wRDYHNHA5BmBsGsMZjDPqfL1 Content-Type: application/json Accept: text/event-stream { "query": "你好", "response_mode": "streaming" } ``` 查看是否能收到流式响应。 --- ### ✅ 4. 检查服务器是否需要认证 如果你的服务器需要登录,你可能需要先: 1. 发送登录请求获取 Cookie 或 Token 2. 在后续请求中带上认证信息 --- ## 🛠️ 建议你做的三件事 ### ✅ 1. 修改 API 地址 尝试修改为: ```csharp apiUrl = "http://localhost/console/api/v1/chat-messages"; ``` 或者: ```csharp apiUrl = "http://localhost/api/v1/chat-messages"; ``` --- ### ✅ 2. 添加 Accept 头 修改请求部分: ```csharp request.SetRequestHeader("Content-Type", "application/json"); request.SetRequestHeader("Authorization", $"Bearer {apiKey}"); request.SetRequestHeader("Accept", "text/event-stream"); // 添加这一行 ``` --- ### ✅ 3. 打印最终请求地址和响应内容 在 `PostChatMessage` 中添加: ```csharp Debug.Log("请求地址: " + apiUrl); Debug.Log("请求内容: " + jsonBody); ``` --- ## ✅ 示例:添加 Accept 头后的完整代码片段 ```csharp UnityWebRequest request = new UnityWebRequest(apiUrl, "POST")) { uploadHandler = new UploadHandlerRaw(rawData), downloadHandler = new DownloadHandlerBuffer() }; request.SetRequestHeader("Content-Type", "application/json"); request.SetRequestHeader("Authorization", $"Bearer {apiKey}"); request.SetRequestHeader("Accept", "text/event-stream"); // 添加这一行 ``` --- ## 📌 总结 | 问题 | 原因 | 解决方案 | |------|------|-----------| | 收到 HTML 响应 | 请求地址可能错误 | 检查 API 地址 | | 未收到流式响应 | 请求头未指定 `Accept` | 添加 `Accept: text/event-stream` | | 接口需要认证 | 未登录或未携带 Cookie | 先登录再请求 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值