当前位置: 首页 > news >正文

Unity InputField + ScrollRect实现微信聊天输入框功能

1、实现动态高度尺寸的的InputField

通过这两个部件就可以实现inputField的动态改变尺寸。

将inputField放入到scrollview当中作为子类

将scrollview 链接到UIChatInputField脚本中。

2、实现UIChatInputField

 //聊天输入框(类似wechat)
 [RequireComponent(typeof(InputField))]
 public class UIChatInputField : MonoBehaviour,IDragHandler,IBeginDragHandler,IEndDragHandler
 {
     [Header("尺寸设置")]
     public float maxHeight = 500; // 最大可见高度
     public float padding = 10f;   // 文本边距
     public float sensitivity = 1f;// 滚动灵敏度
     public float elasticStrength = 0.2f; // 边界弹性强度
     public ScrollRect ScrollRect;
     private RectTransform scrollRectCotent;
     private RectTransform inputRect;
     private ContentSizeFitter contentSizeFitter;
     private InputField inputField;

     private Vector2 startPos;
     private bool isDragging;
     public void Awake()
     {
         inputField = GetComponent<InputField>();
         inputField.onValueChanged.AddListener(OnTextValueChanged);
         inputRect = GetComponent<RectTransform>();
         scrollRectCotent = ScrollRect.content;
         contentSizeFitter = GetComponent<ContentSizeFitter>();
     }

     Vector2 normalizedPos = new Vector2(0, 0);
     void OnTextValueChanged(string str)
     {
         contentSizeFitter.SetLayoutVertical();
         Vector2 sizeDelta = inputRect.sizeDelta;
         ScrollRect.content.sizeDelta = sizeDelta;
         if (inputRect.sizeDelta.y >= maxHeight)
         {
             sizeDelta.y = maxHeight;
         }
         RectTransform rectsCroll = ScrollRect.GetComponent<RectTransform>();
         rectsCroll.sizeDelta = sizeDelta;
         ScrollRect.normalizedPosition = normalizedPos;
     }

     private float GetScrollRange()
     {
         return Mathf.Max(0, scrollRectCotent.rect.height - ScrollRect.viewport.rect.height);
     }

     //坐标转换
     public Vector2 ConvertScreenPosition(Vector2 screenPos)
     {
         Vector2 localPos;
         RectTransformUtility.ScreenPointToLocalPointInRectangle(ScrollRect.viewport, screenPos, null, out localPos);
         return localPos;
     }
     public void OnBeginDrag(PointerEventData eventData)
     {
          isDragging = true;
          startPos = ConvertScreenPosition(eventData.position);
          ScrollRect.StopMovement();
     }

     public void OnDrag(PointerEventData eventData)
     {
         if (!isDragging)
             return;

         Vector2 currentPos = ConvertScreenPosition(eventData.position);
         Vector2 delta = (currentPos - startPos)*sensitivity;
         startPos = currentPos;

         // 转换为标准化位置
         float newNormalizedPos = ScrollRect.verticalNormalizedPosition + delta.y / GetScrollRange();
         newNormalizedPos = Mathf.Clamp01(newNormalizedPos); // 基础限制

         // 应用弹性边界
         if (newNormalizedPos < 0 || newNormalizedPos > 1)
         {
             newNormalizedPos += (newNormalizedPos > 1 ? -1 : 1) * elasticStrength;
         }

         // 更新滚动位置
         ScrollRect.verticalNormalizedPosition = newNormalizedPos;
     }

     public void OnEndDrag(PointerEventData eventData)
     {
         isDragging = false;
     }
 }

效果如:

http://www.dtcms.com/a/54093.html

相关文章:

  • unity学习64,第3个小游戏:一个2D跑酷游戏
  • 如何用更少的内存训练你的PyTorch模型?深度学习GPU内存优化策略总结
  • Linux 上离线安装 python3
  • 哪些培训课程适合学习PostgreSQL中级认证知识?
  • 前端Vue3面试题
  • blender 坐标系 金属度
  • 基于多目标向日葵优化算法(Multi-objective Sunflower Optimization,MOSFO)的移动机器人路径规划研究,MATLAB代码
  • 小程序路径复制
  • 18年老牌软件,完美解锁pro!
  • Java 导出大数据到 Excel 表格
  • DeepSeek group-limited expert routing和负载均衡
  • Secret Cow Code S
  • PS内发光、外发光
  • 关于读写锁:有个线程在读,能写吗?有个线程在写,能读吗?
  • python 同一行显示多条语句
  • 探秘Transformer系列之(9)--- 位置编码分类
  • Java 大视界 -- 基于 Java 的大数据分布式任务调度系统设计与实现(117)
  • Hexo常用指令大全
  • 递归—基础算法
  • 【Java数据结构】前K个高频单词
  • Linux - 网络基础(应用层,传输层)
  • 详细解析MFC第一个桌面应用程序
  • 零基础C语言学习日志23(动态内存管理)
  • Windows下安装VMware Workstation 17并设置支持MacOS
  • 基于单片机的室外休闲智能座椅设计(论文+源码)
  • 第4章 Function 语意学2: Virtual Member Functions
  • merge函数
  • 大模型架构记录2
  • 阿里云 ESA 游戏行业解决方案|安全防护、加速、低延时的技术融合
  • 2025.3.9机器学习笔记:文献阅读