unity3d游戏网络服务器和客户端

本文介绍了一个使用Unity3D客户端与Java Netty UDP服务器实现的简单网络游戏开发案例,包括人物创建、移动同步等功能,并提供了部分Java服务器端代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

想做网络游戏的小伙伴肯定找过 mirro ,Photon的工具 ,但是不是很好用,想自定义强一点,连外网服务器 资料很少或者没有。

我直接用java的netty做的udp服务器就实现了个简单的

 

 

实现了功能有

创建人物,人物移动可以同步。 登录后加载身边的人物。

 

代码

 

这个类初始化netty服务器 ,转发操作命令

package com.hewei.config;


import cn.hutool.core.util.StrUtil;
import com.hewei.game.service.cmd.Command;
import com.hewei.game.vo.CmdVo;
import com.hewei.util.ScanSupport;
import com.hewei.util.SpringUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class BootNettyUdpSimpleChannelInboundHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    Logger logger = LoggerFactory.getLogger(BootNettyUdpSimpleChannelInboundHandler.class);


    Map<String, Constructor> commandMap = new HashMap<>();

    {
        ScanSupport scanSupport = SpringUtil.getBean(ScanSupport.class);
        try {
            Set<Class<?>> classes = scanSupport.doScan("com.hewei.game.service.cmd");
            for (Class<?> aClass : classes) {
                putCmdName((Class<? extends Command>) aClass);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    void putCmdName(Class<? extends Command> clazz) throws NoSuchMethodException {
        String cmd = StrUtil.subBefore(clazz.getSimpleName(), "Cmd", true).toLowerCase();
        Constructor c = clazz.getConstructor(CmdVo.class);//获取有参构造
        commandMap.put(cmd, c);
        logger.info("putCmdName|{}", clazz);
    }


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
        try {

            ByteBuf content = Unpooled.copiedBuffer(packet.content());
            ByteBuf header = content.readBytes(50);
            String s1 = header.toString(CharsetUtil.UTF_8).trim();
            logger.info("channelRead0|{}", s1);
            String[] split = s1.split(":");

            String type = split[0];
            String userId = split[1];

            CmdVo cmdVo = new CmdVo()
                    .setContent(content)
                    .setCtx(ctx)
                    .setHeader(header)
                    .setPacket(packet)
                    .setUserId(userId);
            Command c = (Command) commandMap.get(type).newInstance(cmdVo);
            c.execute();


        } catch (Exception e) {
            logger.error("channelRead0", e);
        }
    }


}

 

 

这个类是命令的公共父类

 

package com.hewei.game.service.cmd;

import com.hewei.game.service.GameCtx;
import com.hewei.game.vo.CmdVo;
import com.hewei.util.ByteUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramPacket;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;

@Slf4j
public abstract class AbsCmd implements Command {


    ChannelHandlerContext ctx;
    String senderUserId;
    DatagramPacket packet;
    ByteBuf content;
    ByteBuf header;
    InetSocketAddress sender;

    CmdVo cmdVo;

    public AbsCmd(CmdVo cmdVo) {
        this.cmdVo = cmdVo;
        this.ctx = cmdVo.ctx;
        this.senderUserId = cmdVo.userId;
        this.packet = cmdVo.packet;
        this.content = cmdVo.content;
        this.header = cmdVo.header;

        this.sender = this.packet.sender();
    }

    public void send2Sender(ByteBuf byteBuf) {

        byteBuf.setIndex(0, byteBuf.writerIndex());
        ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(byteBuf), packet.sender()));
    }



    public void sendSkipSender(ByteBuf byteBuf) {

        for (InetSocketAddress addr : GameCtx.login.values()) {
            if (addr.equals(packet.sender())) {
                continue;
            }
            byteBuf.retain();
            log.info("sendSkipSender-to|{}", addr);
            byteBuf.setIndex(0, byteBuf.writerIndex());
            ctx.writeAndFlush(new DatagramPacket(byteBuf, addr));
        }
    }

    public void sendAll(ByteBuf byteBuf) {
         for (InetSocketAddress addr : GameCtx.login.values()) {

            log.info("sendSkipSender-to|{}", addr);
            byteBuf.retain();
            byteBuf.setIndex(0, byteBuf.writerIndex());
            ctx.writeAndFlush(new DatagramPacket(byteBuf, addr));

        }
    }

    public ByteBuf createHeader(String str){
        byte[] padding = ByteUtil.padding(50, str.getBytes());
        System.out.println(new String(padding));
        return Unpooled.wrappedBuffer(padding);
    }
}

 

代码示例

 

 

 

unity3d的代码

 

 

 

代码太多我已经放到gitee

 

java

留言再给

u3d

https://gitee.com/nhniu/unity3d_udp

 

下一步要实现 心跳 ,战斗

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值